h,ƽP:      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"""""""#####$$$$$$$$$%%&&&&&&'''''((()))))***++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-------------......................................./0000000011111111111122222222222222233444455555555555566666666666677777777778999999999:::::::::::::::::::::;;;;<<===>>>>>>>>>>>>>>????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@AAAAAABBBCCDEEEEEEEEEEEEEEEEEEEEEEEEEFFFGGGGGGGHHHHHIJKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMNOPQQQQQQQQRRRRRRRRRRRRRSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ[\\\\\\\\\\]]]^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^______________________````````````````````````aaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcddddddddeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeefffgghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhiiiiiiiiiiiiijkkkkkkkkkkkkkkllllllllmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnooppqqqqqqqqrrrrrrrrrrrrrrrrrrrrrrrrrssssssssssssssssssssssssssssssssssssssssssssssssttuuvvwwwwxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyzz{{{{{{{{{{{{||}}~~~~~~~~~~~~11.0(c) Levent ErkokBSD3erkokl@gmail.com experimental Safe-InferredZ/SMT-Lib logics. If left unspecified SBV will pick the logic based on what it determines is needed. However, the user can override this choice using a call to  This is especially handy if one is experimenting with custom logics that might be supported on new solvers. See  https://smt-lib.org/logics.shtml for the official list.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.Linear formulas with free sort and function symbols over one- and two-dimentional arrays of integer index and real value.Formulas with free function and predicate symbols over a theory of arrays of arrays of integer index and real value.*Linear formulas in linear real arithmetic.Quantifier-free formulas over the theory of bitvectors and bitvector arrays.Quantifier-free formulas over the theory of bitvectors and bitvector arrays extended with free sort and function symbols.Quantifier-free linear formulas over the theory of integer arrays extended with free sort and function symbols.Quantifier-free formulas over the theory of arrays with extensionality. Quantifier-free formulas over the theory of fixed-size bitvectors. 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. Unquantified linear integer arithmetic. In essence, Boolean combinations of inequations between linear polynomials over integer variables. Unquantified linear real arithmetic. In essence, Boolean combinations of inequations between linear polynomials over real variables. #Quantifier-free integer arithmetic. Quantifier-free real arithmetic.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.Unquantified formulas built over a signature of uninterpreted (i.e., free) sort and function symbols.Unquantified formulas over bitvectors with uninterpreted sort function and symbols.Difference Logic over the integers (in essence) but with uninterpreted sort and function symbols.Unquantified linear integer arithmetic with uninterpreted sort and function symbols.Unquantified linear real arithmetic with uninterpreted sort and function symbols.Unquantified non-linear real arithmetic with uninterpreted sort and function symbols.Unquantified non-linear real integer arithmetic with uninterpreted sort and function symbols.Linear real arithmetic with uninterpreted sort and function symbols.Non-linear integer arithmetic with uninterpreted sort and function symbols.Quantifier-free formulas over the theory of floating point numbers, arrays, and bit-vectors.Quantifier-free formulas over the theory of floating point numbers.Quantifier-free finite domains.4Quantifier-free formulas over the theory of strings.The catch-all value.=Use this value when you want SBV to simply not set the logic.(In case you need a really custom string! Option values that can be set in the solver, following the SMTLib specification  "https://smt-lib.org/language.shtml.3Note that not all solvers may support all of these!Furthermore, SBV doesn't support the following options allowed by SMTLib.:interactive-mode+ (Deprecated in SMTLib, use " instead.):print-success (SBV critically needs this to be True in query mode.):produce-models (SBV always sets this option so it can extract models.):regular-output-channel (SBV always requires regular output to come on stdout for query purposes.):global-declarations (SBV always uses global declarations since definitions are accumulative.) Note that - and . are, strictly speaking, not SMTLib options. However, we treat it as such here uniformly, as it fits better with how options work./(Collectable information from the solver.9Reason for reporting unknown.>"Behavior of the solver for errors.A(Collectable information from the solver.J Result of a  or  call.K=Satisfiable: A model is available, which can be queried with .LDelta-satisfiable: A delta-sat model is available. String is the precision info, if available.MUnsatisfiable: No model is available. Unsat cores might be obtained via .N Unknown: Use 5 to obtain an explanation why this might be the case.7Can this command only be run at the very beginning? If  then we will reject setting these options in the query mode. Note that this classification follows the SMTLib document.Can this option be set multiple times? I'm only making a guess here. If this returns True, then we'll only send the last instance we see. We might need to update as necessary.Translate an option setting to SMTLib. Note the SetLogic/SetInfo discrepancy.Show instance for unknownTrivial rnf instanceJLKNM  >@?ABCDEIFGH/123485607 !,("#%$&')*+.-9;:=<(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone8cO4Conversion from internal rationals to Haskell valuesP'Root of a polynomial, cannot be reducedQAn exact rationalRAn approximated valueS*Interval. Can be open/closed on both ends.TA univariate polynomial, represented simply as a coefficient list. For instance, "5x^3 + 2x - 5" is represented as [(5, 3), (2, 1), (-5, 0)]VAlgebraic reals. Note that the representation is left abstract. We represent rational results explicitly, while the roots-of-polynomials are represented implicitly by their defining equationWbool says it's exact (i.e., SMT-solver did not return it with ? at the end.)Xwhich root of this polynomial and an approximate decimal representation with given precision, if availableY"interval, with low and high boundsZ)Is the endpoint included in the interval?[%open: i.e., doesn't include the point\ closed: i.e., includes the point]7Extract the point associated with the open-closed point3Check whether a given argument is an exact rationalConstruct a poly-root real with a given approximate value (either as a decimal, or polynomial-root)Structural equality for AlgReal; used when constants are Map keysStructural comparisons for AlgReal; used when constants are Map keys Render an V as an SMTLib2 value. Only supports rationals for the time being. Render an V as a Haskell value. Only supports rationals, since there is no corresponding standard Haskell type that can represent root-of-polynomial variety.^ Convert an V to a  . If the V is exact, then you get a  value. Otherwise, you get a ( value which is simply an approximation.Merge the representation of two algebraic reals, one assumed to be in polynomial form, the other in decimal. Arguments can be the same kind, so long as they are both rationals and equivalent; if not there must be one that is precise. It's an error to pass anything else to this function! (Used in reconstructing SMT counter-example values with reals).NB: Following the other types we have, we require `a/0` to be `0` for all a.^]VYXWTUORQSPZ\[(c) Levent ErkokBSD3erkokl@gmail.com experimental Safe-Inferredd_Names reserved by SMTLib. This list is current as of Dec 6 2015; but of course there's no guarantee it'll stay that way._(c) Brian SchroederBSD3erkokl@gmail.com experimental Safe-Inferredg`Monads which support  operations and can extract all 2 behavior for interoperation with functions like , which takes an  action in negative position. This function can not be implemented for transformers like  ReaderT r or StateT s, whose resultant 6 actions are a function of some environment or state.a Law: the m a yielded by  is pure with respect to .IO extraction for strict .IO extraction for lazy .IO extraction for .IO extraction for .Trivial IO extraction for .`a(c) Levent ErkokBSD3erkokl@gmail.com experimental Safe-Inferredl\ We have a nasty issue with the usual String/List confusion in Haskell. However, we can do a simple dynamic trick to determine where we are. The ice is thin here, but it seems to work.Monadic lift over 2-tuplesMonadic lift over 3-tuplesMonadic lift over 4-tuplesMonadic lift over 5-tuplesMonadic lift over 6-tuplesMonadic lift over 7-tuplesMonadic lift over 8-tuplesGiven a sequence of arguments, join them together in a manner that could be used on the command line, giving preference to the Windows cmd shell quoting conventions.For an alternative version, intended for actual running the result in a shell, see "System.Process.showCommandForUser"Given a string, split into the available arguments. The inverse of #. Courtesy of the cmdargs package.Given an SMTLib string (i.e., one that works in the string theory), convert it to a Haskell equivalentGiven 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.$Check if an observable name is good. (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone(18>zbRounding mode to be used for the IEEE floating-point operations. Note that Haskell's default is c. If you use a different rounding mode, then the counter-examples you get may not match what you observe in Haskell.cRound 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.)dRound 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.)eRound towards positive infinity. (Also known as rounding-up or ceiling.)fRound towards negative infinity. (Also known as rounding-down or floor.)g/Round towards zero. (Also known as truncation.)hA valid float has restrictions on eb/sb values. NB. In the below encoding, I found that CPP is very finicky about substitution of the machine-dependent macros. If you try to put the conditionals in the same line, it fails to substitute for some reason. Hence the awkward spacing. Filed this as a bug report for CPPHS at  1https://github.com/malcolmwallace/cpphs/issues/25.Catch an invalid FP.i9Type family to create the appropriate non-zero constraintCatch 0-width casesjA 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  instance; this is useful for creating uninterpreted sorts. So, in reality, end users should almost never need to define any methods.Kind of symbolic value;A version of show for kinds that says Bool instead of SBoolPut parens if necessary. This test is rather crummy, but seems to work okHow the type maps to SMT land+Does this kind represent a signed quantity?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 uninterpretedGrab 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 really deal with in any practical realm.) In fact, even the range allowed by this conversion (i.e., the entire range of a 64-bit int) is just impractical, but it's hard to come up with a better bound.Is this a type we can safely do equality on? Essentially it avoids floats (NaN /= NaN, +0 = -0), and reals (due to the possible presence of non-exact rationals.Do we have a completely uninterpreted sort lying around anywhere?Should we ask the solver to flatten the output? This comes in handy so output is parseable Essentially, we're being conservative here and simply requesting flattening anything that has some structure to it.;Convert a rounding mode to the format SMT-Lib2 understands.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 <, we make sure we don't use any of the reserved names; see  for details.This instance allows us to use the `kindOf (Proxy @a)` idiom instead of the `kindOf (undefined :: a)`, which is safer and looks more idiomatic.b kind8ijlm~nowr}tqy|spzx{uvkbdcfegh(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 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:  ,http://ghc.haskell.org/trac/ghc/ticket/10378  'http://github.com/Z3Prover/z3/issues/68 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 SMTLib compliant definition for . See the comments for ..Convert double to float and back. Essentially fromRational . toRational, except careful on NaN, Infinities, and -0.Compute the "floating-point" remainder function, the float/double value that remains from the division of x and y. There are strict rules around 0's, Infinities, and NaN's as coded below.Convert a float to the nearest integral representable in that typeCheck that two floats are the exact same values, i.e., +0/-0 does not compare equal, and NaN's compare equal to themselves.$Ordering for floats, avoiding the +0-0NaN issues. Note that this is essentially used for indexing into a map, so we need to be total. Thus, the order we pick is: NaN -oo -0 +0 +oo The placement of NaN here is questionable, but immaterial.Check if a number is "normal." Note that +0/-0 is not considered a normal-number and also this is not simply the negation of isDenormalized!Reinterpret-casts a  to a .Reinterpret-casts a  to a .Reinterpret-casts a  to a .Reinterpret-casts a  to a . (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 18!1Internal representation of a parameterized float.A note on cardinality: If we have eb exponent bits, and sb significand bits, 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.Abbreviation for IEEE quadruble precision float, bit width 128 = 15 + 113.Abbreviation for IEEE double precision float, bit width 64 = 11 + 53.Abbreviation for IEEE single precision float, bit width 32 = 8 + 24.Abbreviation for brain-float precision float, bit width 16 = 8 + 8.Abbreviation for IEEE half precision float, bit width 16 = 5 + 11.A floating point value, indexed by its exponent and significand sizes.An IEEE SP is FloatingPoint 8 24 DP is FloatingPoint 11 53 etc. NB. Don't derive Ord for this type automatically, see notes below.Remove redundant p+0 etc.Show a big float in the base given. NB. Do not be tempted to use BF.showFreeMin below; it produces arguably correct but very confusing results. See  0https://github.com/GaloisInc/cryptol/issues/1089! for a discussion of the issues.Default options for BF options.,Construct a float, by appropriately roundingConvert from an signexponentmantissa 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.Make NaN. Exponent is all 1s. Significand is non-zero. The sign is irrelevant.4Make Infinity. Exponent is all 1s. Significand is 0.Make a signed zero.Make from an integer value./Make a generalized floating-point value from a ."Represent the FP in SMTLib2 formatCheck that two arbitrary floats are the exact same values, i.e., +0/-0 does not compare equal, and NaN's compare equal to themselves.Ordering for arbitrary floats, avoiding the +0-0NaN issues. Note that this is essentially used for indexing into a map, so we need to be total.This function uses the bfCompare function provided by the libBF. As per the libBF's documentation, it has the semantics: -0 < 0, NaN == NaN, and NaN is larger than all other numbers.!Compute the signum of a big floatEncode from exponent/mantissa form to a float representation. Corresponds to  in Haskell.Lift a unary operation, simple case of function with no status. Here, we call fpFromBigFloat since the big-float isn't size aware.Convert from a IEEE float.Convert from a IEEE double.Real-frac instance for big-floats. Beware, not that well tested!;Real instance for big-floats. Beware, not that well tested!Real-float instance for big-floats. Beware! Some of these aren't really all that well tested. Floating instance for big-floats"Fractional instance for big-floatsNum instance for big-floatsNum instance for FloatingPointShow instance for Floats. By default we print in base 10, with standard scientific notation.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNonea(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone8/A simple expression type over extended values, covering infinity, epsilon and intervals.A generalized CV allows for expressions involving infinite and epsilon values/intervals Used in optimization problems. represents a concrete word of a fixed size: For signed words, the most significant digit is considered to be the sign.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"!Algebraic realBit-vector/unbounded integerFloatDoubleArbitrary floatRational CharacterStringList$Set. Can be regular or complemented.Value of an uninterpreted/user kind. The Maybe Int shows index position for enumerationsTupleMaybeDisjoint union.Arrays are backed by look-up tables concretelyUnderlying type for SMTLib arrays, as a list of key-value pairs, with a default for unmapped elements. Note that this type matches the typical models returned by SMT-solvers. When we store the array, we do not bother removing earlier writes, so there might be duplicates. 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.A  is either a regular set or a set given by its complement from the corresponding universal set.Structural equality for  . We need EqOrd instances for $ because we want to put them in mapstables. But we don't want to derive these, nor make it an instance! Why? Because the same set can have multiple representations if the underlying type is finite. For instance, {True} = U - {False} for boolean sets! Instead, we use the following two functions, which are equivalent to Eq/Ord instances and work for our purposes, but we do not export these to the user. Comparing  values. See comments for  on why we don't define the  instance.Assign a rank to constant values, this is structural and helps with ordering*Show an extended CV, with kind if requiredIs this a regular CV?Are two CV's of the same type?Convert a CV to a Haskell boolean (NB. Assumes input is well-kinded)Normalize a CV. Essentially performs modular arithmetic to make sure the value can fit in the given bit-size. Note that this is rather tricky for negative values, due to asymmetry. (i.e., an 8-bit negative number represents values in the range -128 to 127; thus we have to be careful on the negative side.)Constant False as a ,. We represent it using the integer value 0.Constant True as a ,. We represent it using the integer value 1.Map a unary function through a . Map a binary function through a .)Show a CV, with kind info if bool is True(Create a constant word from an integral."Generate a random constant value () of the correct kind."Generate a random constant value () of the correct kind.Show instance. Regular sets are shown as usual. Complements are shown "U -" notation.The kind of an ArrayModel,Ord instance for CVal. Same comments as the % instance why this cannot be derived.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 need a structural eq/ord for Map indexes; so define custom ones here:Show instance for . instance for CV"Show instance, shows with the kindKind instance for Extended CVShow instance for Generalized  instance for generalized CV3(c) Levent ErkokBSD3erkokl@gmail.com experimental Safe-Inferredz2Specify how to save timing information, if at all.Show  in human readable form.  is essentially picoseconds (10^-12 seconds). We show it so that it's represented at the day:hour:minute:second.XXX granularity.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone"'()*78:=>?Query execution contextTriggered from inside SBVTriggered from user code An SMT solver"Various capabilities of the solver=The solver engine, responsible for interpreting solver output Options to provide to the solverEach line sent to the solver will be passed through this function (typically id)The path to its executableThe solver in useSolvers that SBV is aware of An SMT engine%A script, to be passed to the solver.'Continuation script, to extract results Initial feedThe result of an SMT solver call. Each constructor is tagged with the  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.)Unsatisfiable. If unsat-cores are enabled, they will be returned in the second parameter.Satisfiable with model |x|. In this case, wrap-around can happen, so we reduce by the size of |x|. Case 2.2. Finite i, and it can't contain a value > |x|. In this case, no reduction is needed.Overflow detection.Create a symbolic two argument operation; with shortcut optimizationsCreate a symbolic two argument operation; no shortcut optimizations)Predicate to check if a value is concretePredicate for optimizing word operations like (+) and (*). NB. We specifically do *not* match for Double/Float; because FP-arithmetic doesn't obey traditional rules. For instance, 0 * x = 0 fails if x happens to be NaN or +/- Infinity. So, we merely return False when given a floating-point value here.Predicate for optimizing word operations like (+) and (*). NB. See comment on 6 for why we don't match for Float/Double values here.Predicate for optimizing bitwise operations. The unbounded integer case of checking against -1 might look dubious, but that's how Haskell treats % as a member of the Bits class, try (-1 :: Integer)  i for any i and you'll get .%Predicate for optimizing comparisons.%Predicate for optimizing comparisons.Most operations on concrete rationals require a compatibility check to avoid faulting on algebraic reals.;Quot/Rem operations require a nonzero check on the divisor.'Same as rationalCheck, except for SBV'sGiven a composite structure, figure out how to compare for less thanStructural less-than for tuplesStructural less-than for maybesStructural less-than for either Convert an  to an , preserving the bit-correspondence. Note that since the representation for NaNs are not unique, this function will return a symbolic value when given a concrete NaN.Implementation note: Since there's no corresponding function in SMTLib for conversion to bit-representation due to partiality, we use a translation trick by allocating a new word variable, converting it to float, and requiring it to be equivalent to the input. In code-generation mode, we simply map it to a simple conversion. Convert an  to an , preserving the bit-correspondence. Note that since the representation for NaNs are not unique, this function will return a symbolic value when given a concrete NaN.Implementation note: Since there's no corresponding function in SMTLib for conversion to bit-representation due to partiality, we use a translation trick by allocating a new word variable, converting it to float, and requiring it to be equivalent to the input. In code-generation mode, we simply map it to a simple conversion.Convert a float to the word containing the corresponding bit pattern(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 11**A signed bit-vector carrying its size info-An unsigned bit-vector carrying its size infoQuickcheck instance for WordN instance for  instance for  instance for  instance for  instance for  has a kindShow instance for Quickcheck instance for IntN instance for  instance for  instance for  instance for  instance for  has a kindShow instance for (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone13=>?k,Class of things that we can logically negateNegation of a quantified formula. This operation essentially lifts  to quantified formulae. Note that you can achieve the same using  . , but that will hide the quantifiers, so prefer this version if you want to keep them around.A class of values that can be skolemized. Note that we don't export this class. Use the  function instead.Skolemization. For any formula, skolemization gives back an equisatisfiable formula that has no existential quantifiers in it. You have to provide enough names for all the existentials in the argument. (Extras OK, so you can pass an infinite list if you like.) The names should be distinct, and also different from any other uninterpreted name you might have elsewhere.If you use the same names for skolemized arguments in different functions, they will collide; which is undesirable. Unfortunately there's no easy way for SBV to detect this. In such cases, use 7 to add a scope to the skolem-function names generated.5Not exported, used for implementing generic equality.4Symbolic Equality. Note that we can't use Haskell's  class since Haskell insists on returning Bool Comparing symbolic values will necessarily return a symbolic value.NB. Equality is a built-in notion in SMTLib, and is object-equality. While this mostly matches Haskell's notion of equality, the correspondence isn't exact. This mostly shows up in containers with floats inside, such as sequences of floats, sets of doubles, and arrays of doubles. While SBV tries to maintain Haskell semantics, it does resort to container equality for compound types. For instance, for an IEEE-float, -0 == 0. But for an SMTLib sequence, equals is done over objects. i.e.,  [0] == [-0] in Haskell, but literal [0] ./= literal [-0] when used as SMTLib sequences. The rabbit-hole goes deep here, especially when NaN is involved, which does not compare equal to itself per IEEE-semantics.If you are not using floats, then you can ignore all this. If you do, then SBV will do the right thing for them when checking equality directly, but not when you use containers with floating-point elements. In the latter case, object-equality will be used.>Minimal complete definition: None, if the type is instance of Generic . Otherwise .Symbolic equality.Symbolic inequality.Strong equality. On floats (/0), strong equality is object equality; that is  NaN == NaN holds, but +0 == -0 doesn't. On other types, (.===) is simply (.==). Note that (.==) is the right notion of equality for floats per IEEE754 specs, since by definition +0 == -0 and NaN equals no other value including itself. But occasionally we want to be stronger and state NaN equals NaN and +0 and -0 are different from each other. In a context where your type is concrete, simply use . But in a polymorphic context, use the strong equality instead.NB. If you do not care about or work with floats, simply use (.==) and (./=).Negation of strong equality. Equaivalent to negation of (.===) on all types.Returns (symbolic) 5 if all the elements of the given list are different.Returns (symbolic)  if all the elements of the given list are different. The second list contains exceptions, i.e., if an element belongs to that set, it will be considered distinct regardless of repetition.Returns (symbolic) 4 if all the elements of the given list are the same.Symbolic membership test.!Symbolic negated membership test.A  is a potential symbolic value that can be created instances of to be fed to a symbolic program.Generalization of #Turn a literal constant to symbolic+Extract a literal, from a CV representation/Does it concretely satisfy the given predicate?Generalization of Generalization of Generalization of Generalization of Generalization of +Extract a literal, if the value is concreteIs the symbolic word concrete?%Is the symbolic word really symbolic?A class representing what can be returned from a symbolic computation.Generalization of Actions we can do in a context: Either at problem description time or while we are dynamically querying.  and  are two instances of this class. Note that we use this mechanism internally and do not export it from SBV.Add a constraint, any satisfying instance must satisfy this condition.Add a soft constraint. The solver will try to satisfy this condition if possible, but won't if it cannot.Add a named constraint. The name is used in unsat-core extraction.,Add a constraint, with arbitrary attributes.Set info. Example: setInfo ":status" ["unsat"].Set an option.Set the logic.Set a solver time-out value, in milli-seconds. This function essentially translates to the SMTLib call (set-info :timeout val), and your backend solver may or may not support it! The amount given is in milliseconds. Also see the function : for finer level control of time-outs, directly from SBV.*Get the state associated with this context0A value that can be used as a quantified booleanTurn a quantified boolean into a regular boolean. That is, this function turns an exists/forall quantified formula to a simple boolean that can be used as a regular boolean value. An example is:  quantifiedBool $ \(Forall x) (Exists y) -> y .> (x :: SInteger) is equivalent to . You can think of this function as performing quantifier-elimination: It takes a quantified formula, and reduces it to a simple boolean that is equivalent to it, but has no quantifiers.1Values that we can turn into a lambda abstractionExactly n universal symbolic variables, used in in building quantified constraints. The name attached will be prefixed in front of _1, _2, ..., _n$ to form the names of the variables.Exactly n existential 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.A universal symbolic variable, used in building quantified constraints. The name attached via the symbol is used during skolemization. It names the corresponding argument to the skolem-functions within the scope of this quantifier.An existential unique symbolic variable, used in building quantified constraints. The name attached via the symbol is used during skolemization. It's split into two extra names, suffixed _eu1 and _eu25, to name the universals in the equivalent formula: \exists! x\,P(x)\Leftrightarrow \exists x\,P(x) \land \forall x_{eu1} \forall x_{eu2} (P(x_{eu1}) \land P(x_{eu2}) \Rightarrow x_{eu1} = x_{eu2}) An existential symbolic variable, used in building quantified constraints. The name attached via the symbol is used during skolemization to create a skolem-function name when this variable is eliminated.)Values that we can turn into a constraintThe symbolic variant of b7Internal representation of a symbolic simulation result'SMTLib representation, given the configSymbolic 8-tuple.Symbolic 7-tuple.Symbolic 6-tuple.Symbolic 5-tuple.Symbolic 4-tuple.Symbolic 3-tuple.Symbolic 2-tuple. NB.  and  are equivalent.Symbolic 2-tuple. NB.  and  are equivalent. Symbolic . Note that we use , which supports both regular sets and complements, i.e., those obtained from the universal set (of the right type) by removing elements. Similar to  the contents are stored with object equality, which makes a difference if the underlying type contains IEEE Floats.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 the same as regular equality for most types, except for IEEE-Floats, where NaN& doesn't compare equal to itself and +0 and -0 are not distinguished. So, if your index type is a float, then NaN can be stored correctly, and 0 and -0 will be distinguished. If you don't use floats, then you can treat this the same as regular equality in Haskell. Symbolic  Symbolic 7A symbolic list of items. Note that a symbolic list is not= a list of symbolic items, that is, it is not the case that  SList a = [a], unlike what one might expect following haskell lists/sequences. An  is a symbolic value of its own, of possibly arbitrary but finite length, and internally processed as one unit as opposed to a fixed-length list of items. Note that lists can be nested, i.e., we do allow lists of lists of ... items.A symbolic rational value.2A symbolic string. Note that a symbolic string is not a list of symbolic characters, that is, it is not the case that SString = [SChar]>, unlike what one might expect following Haskell strings. An  is a symbolic value of its own, of possibly arbitrary but finite length, and internally processed as one unit as opposed to a fixed-length list of characters.A symbolic character. Note that this is the full unicode character set. see:  1https://smt-lib.org/theories-UnicodeStrings.shtml for details.3A symbolic signed bit-vector carrying its size info5A symbolic unsigned bit-vector carrying its size infoA symbolic quad-precision float!A symbolic double-precision float!A symbolic single-precision float&A symbolic brain-float precision floatA symbolic half-precision float3A symbolic arbitrary precision floating point value0IEEE-754 double-precision floating point numbers0IEEE-754 single-precision floating point numbers0Infinite precision symbolic algebraic real value(Infinite precision signed symbolic value;64-bit signed symbolic value, 2's complement representation;32-bit signed symbolic value, 2's complement representation;16-bit signed symbolic value, 2's complement representation:8-bit signed symbolic value, 2's complement representation64-bit unsigned symbolic value32-bit unsigned symbolic value16-bit unsigned symbolic value8-bit unsigned symbolic valueA symbolic boolean/bitThe Symbolic value. The parameter a is phantom, but is extremely important in keeping the user interface strongly typed.Get the current path condition4Extend the path condition with the given test value.Not-A-Number for  and . Surprisingly, Haskell Prelude doesn't have this value defined, so we provide it here. Infinity for  and . Surprisingly, Haskell Prelude doesn't have this value defined, so we provide it here.;Symbolic variant of Not-A-Number. This value will inhabit ,  and . types. 0An internal type to track of solver interactions All is wellTimeout expiredSomething else went wrong6Various SMT results that we can extract models out of.Is there a model?Extract assignments of 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.)Extract a model dictionary. Extract a dictionary mapping the variables to their respective values as returned by the SMT solver. Also see .4Extract a model value for a given element. Also see .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 .A simpler variant of % to get a model out without the fuss.;Extract model objective values, for all optimization goals.!Extract the value of an objective%Extract model uninterpreted-functionsExtract the value of an uninterpreted-function as an association list Instances of  can be automatically extracted from models returned by the solvers. The idea is that the sbv infrastructure provides a stream of CV's (constant values) coming from the solver, and the type a is interpreted based on these constants. Many typical instances are already provided, so new instances can be declared with relative ease.Minimum complete definition: 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 2Given 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.An  call results in a  . In the  case, the boolean is  if we reached pareto-query limit and so there might be more unqueried results remaining. If , it means that we have all the pareto fronts returned. See the   for details.A  call results in a An  call results in a All satisfying models3Did the solver report delta-satisfiable at the end?)Did the solver report unknown at the end?.Did we reach the user given model count limit?A  call results in a # The reason for having a separate  is to have a more meaningful  instance.A  call results in a -Extract the final configuration from a result*What's the precision of a delta-sat query?1Parse a signed/sized value from a sequence of CVsReturn all the models from an  call, similar to 3 but is suitable for the case of multiple results.2Get dictionaries from an all-sat call. Similar to .=Extract value of a variable from an all-sat call. Similar to .Extract value of an uninterpreted variable from an all-sat call. Similar to .Extract a model out, will throw error if parsing is unsuccessful Given an  call, we typically want to iterate over it and print the results in sequence. The ) function automates this task by calling disp+ on each result, consecutively. The first  argument to disp 'is the current model number. The second argument is a tuple, where the first element indicates whether the model is alleged (i.e., if the solver is not sure, returning Unknown). The arrange argument can sort the results in any way you like, if necessary."Show an SMTResult; generic versionShow a model in human readable form. Ignore bindings to those variables that start with "__internal_sbv_" and also those marked as "nonModelVar" in the config; as these are only for internal purposes:Show bindings in a generalized model dictionary, tabulatedShow an uninterpreted function1Show a constant value, in the user-specified base-Helper function to spin off to an SMT solver.A standard engine interface. Most solvers follow-suit here in how we "chat" to them..A standard solver interface. If the solver is SMT-Lib compliant, then this function should suffice in communicating with it. A variant of readProcessWithExitCode(; except it deals with SBV continuationsCompute and report the end time&Start a transcript file, if requested.Finish up the transcript file.7-Tuples extracted from a model6-Tuples extracted from a model5-Tuples extracted from a model4-Tuples extracted from a model3-Tuples extracted from a modelTuples extracted from a modelA list of values as extracted from a model. When reading a list, we go as long as we can (maximal-munch). Note that this never fails, as we can always return the empty list! as extracted from a model as extracted from a modelA rounding mode, extracted from a model. (Default definition suffices)CV. as extracted from a model; trivial definitionConstructing models for Constructing models for /A general floating-point extracted from a model as extracted from a model as extracted from a modelV as extracted from a model as extracted from a model as extracted from a model as extracted from a model as extracted from a model as extracted from a model as extracted from a model as extracted from a model as extracted from a model as extracted from a model as extracted from a modelBase case for = at unit type. Comes in handy if there are no real variables. as a generic model provider as a generic model provider as a generic model providerThe current configurationContext in which we are running The programThe continuation((c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneThe description of the Z3 SMT solver. The default executable is "z3"., which must be in your path. You can use the SBV_Z3 environment variable to point to the executable on your system. You can use the SBV_Z3_OPTIONS. environment variable to override the options.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneThe description of the Yices SMT solver The default executable is  "yices-smt2"., which must be in your path. You can use the  SBV_YICES environment variable to point to the executable on your system. You can use the SBV_YICES_OPTIONS. environment variable to override the options.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneThe description of the OpenSMT SMT solver. The default executable is  "opensmt"., which must be in your path. You can use the  SBV_OpenSMT environment variable to point to the executable on your system. You can use the SBV_OpenSMT_OPTIONS. environment variable to override the options.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneThe description of the MathSAT SMT solver The default executable is  "mathsat"., which must be in your path. You can use the  SBV_MATHSAT environment variable to point to the executable on your system. You can use the SBV_MATHSAT_OPTIONS. environment variable to override the options.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone.The description of the dReal SMT solver The default executable is "dReal"., which must be in your path. You can use the  SBV_DREAL environment variable to point to the executable on your system. You can use the SBV_DREAL_OPTIONS. environment variable to override the options.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneThe description of the CVC5 SMT solver The default executable is "cvc5"., which must be in your path. You can use the SBV_CVC5 environment variable to point to the executable on your system. You can use the SBV_CVC5_OPTIONS. environment variable to override the options.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone6The description of the CVC4 SMT solver The default executable is "cvc4"., which must be in your path. You can use the SBV_CVC4 environment variable to point to the executable on your system. You can use the SBV_CVC4_OPTIONS. environment variable to override the options.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneThe description of the Boolector SMT solver The default executable is  "boolector"., which must be in your path. You can use the  SBV_BOOLECTOR environment variable to point to the executable on your system. You can use the SBV_BOOLECTOR_OPTIONS. environment variable to override the options.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone\The description of the Bitwuzla SMT solver The default executable is  "bitwuzla"., which must be in your path. You can use the  SBV_BITWUZLA environment variable to point to the executable on your system. You can use the SBV_BITWUZLA_OPTIONS. environment variable to override the options.(c) Adam FoltzerBSD3erkokl@gmail.com experimentalNone$2The description of abc. The default executable is "abc"/, which must be in your path. You can use the SBV_ABC environment variable to point to the executable on your system. The default options are 6-S "%blast; &sweep -C 5000; &syn4; &cec -s -m -C 2000". You can use the SBV_ABC_OPTIONS. environment variable to override the options.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone '< Maka a new substate from the incoming state, sharing parts as necessary%Generic creator for anonymous lamdas.,Create an SMTLib lambda, in the given state.7Create an anonymous lambda, rendered as n SMTLib string%Generaic creator for named functions,3Create a named SMTLib function, in the given state.Create a named SMTLib function, in the given state, string versionGeneric constraint generator.Generate a constraint.%Generate a constraint, string version0Convert to an appropriate SMTLib representation.Convert the result of a symbolic run to a more abstract representation)A constraint can be turned into a boolean(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone"'(>6A class which allows for sexpr-conversion to functionsAdding a constraint, possibly with attributes and possibly soft. Only used internally. Use  and  from user programs.Get the current configurationGet the objectivesGet the programGet the assertions put in via Generalization of >Sync-up the external solver with new context we have generatedRetrieve the query contextGeneralization of Generalization of Generalization of Generalization of Generalization of We need to track sent asserts/check-sat calls so we can issue an extra check-sat call if neededGeneralization of Send a string to the solver, and return the response. Except, if the response is one of the "ignore" ones, keep querying.Generalization of Generalization of Generalization of Registering an uninterpreted SMT function. This is typically not necessary as uses of the UI function itself will register it automatically. But there are cases where doing this explicitly can come in handy, typically in query contexts.&Register a kind with the solver. Like , this is typically not necessary since SBV will register kinds as it encounters them automatically. But there are cases where doing this can explicitly can come handy, typically in query contexts.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.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.Generalization of Generalization of Get the value of a term, but in CV form. Used internally. The model-index, in particular is extremely Z3 specific! 5"Make up" a CV for this type. Like zero, but smarter. $Go from an SExpr directly to a value Recover a given solver-printed value with a possible interpretation Generalization of  Retrieve value from the solver Generalization of  Generalization of Generalization of Generalization of  What are the top level inputs? Trackers are returned as top level existentialsGet observables, i.e., those explicitly labeled by the user with a call to . Get UIs, both constants and functions. This call returns both the before and after query ones. Generalization of . Return all satisfying models. Generalization of Generalization of  Bail out if a parse goes bad Generalization of  (Convert a query result to an SMT Problem Generalization of   as a . Curried functions of arity 8 Curried functions of arity 7 Curried functions of arity 6 Curried functions of arity 5 Curried functions of arity 4 Curried functions of arity 3 Curried functions of arity 2 Functions of arity 8 Functions of arity 7 Functions of arity 6 Functions of arity 5 Functions of arity 4 Functions of arity 3 Functions of arity 2 Functions of arity 1    *          (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone'($  An Assignment of a model bindingGeneralization of Generalization of Generalization of Generalization of Generalization of  Classify a model based on whether it has unbound objectives or not. Generalization of  Generalization of  Generalization of Generalization of  Get a model stored at an index. This is likely very Z3 specific! Just after a check-sat is issued, collect objective values. Used internally only, not exposed to the user.Generalization of Generalization of  Helper for the two variants of checkSatAssuming we have. Internal only.Generalization of  ;Upon a pop, we need to restore all arrays and tables. See: ,http://github.com/LeventErkok/sbv/issues/374Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of  Retrieve the unsat core if it was asked for in the configurationGeneralization of Generalization of  . Use this version with MathSAT.Generalization of .Generalization of .Generalization of . Use this version with Z3.Generalization of Generalization of Make an assignment. The type  1 is abstract, the result is typically passed to :  mkSMTResult [ a |-> 332 , b |-> 2.3 , c |-> True ] End users should use  for automatically constructing models from the current solver state. However, an explicit   might be handy in complex scenarios where a model needs to be created manually.Generalization of  NB. This function does not allow users to create interpretations for UI-Funs. But that's probably not a good idea anyhow. Also, if you use the  or ? features, SBV will fail on models returned via this function.     JLKNM  >@?ABCDEIFGH/123485607 !,("#%$&')*+.-9;:=<1(c) Brian Schroeder Levent ErkokBSD3erkokl@gmail.com experimentalNone5Run a custom query.JLKNM>@?ABCDEIFGH/123485607 !,("#%$&')*+.-`a`aJKLMNAHFBCDEGI>?@/012345678 !"#$%&'()*+,-.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone '/Symbolically executable program fragments. This class is mainly used for  calls, and is sufficiently populated internally to cover most use cases. Users can extend it as they wish to allow  checks for SBV programs that return/take types that are user-defined.Generalization of Generalization of Generalization of A type a is provable if we can turn it into a predicate, i.e., it has to return a boolean. This class captures essentially prove calls."Reduce an arg, for proof purposes.Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of A type a is satisfiable if it has constraints, potentially returning a boolean. This class captures essentially sat and optimize calls. Reduce an arg, for sat purposes.Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of Generalization of  is specialization of  to the  monad. Unless you are using transformers explicitly, this is the type you should prefer. is specialization of  to the  monad. Unless you are using transformers explicitly, this is the type you should prefer.A constraint set is a symbolic program that returns no values. The idea is that the constraints/min-max goals will serve as the collection of constraints that will be used for sat/optimize calls.A predicate is a symbolic program that returns a (symbolic) boolean value. For all intents and purposes, it can be treated as an n-ary function from symbolic-values to a boolean. The  monad captures the underlying representation, and can/should be ignored by the users of the library, unless you are building further utilities on top of SBV itself. Instead, simply use the  type when necessary. If supported, this makes all output go to stdout, which works better with SBV Alas, not all solvers support it..Default configuration for the ABC synthesis and verification tool.2Default configuration for the Boolector SMT solver1Default configuration for the Bitwuzla SMT solver.Default configuration for the CVC4 SMT Solver..Default configuration for the CVC5 SMT Solver./Default configuration for the Yices SMT Solver.0Default configuration for the MathSAT SMT solver/Default configuration for the Yices SMT Solver.+Default configuration for the Z3 SMT solver0Default configuration for the OpenSMT SMT solvera Equality as a proof method. Allows for very concise construction of equivalence proofs, which is very typical in bit-precise proofs.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  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  MetricSpace3 is not identical to the type, you want to define , and possibly   ' to add extra constraints as necessary.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  comparable counterparts, etc.%Compute the metric value to optimize.=Compute the value itself from the metric corresponding to it.Annotate for the metric space, to clarify the new name. If this result is not identity, we will add an sObserve on the original.Minimizing a metric spaceMaximizing a metric space Kind of uninterpretation completely uninterpreted. If Bool is true, then this is curried. 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. %has code for code-generation, i.e., CSMT 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: . However, most instances in practice are already provided by SBV, so end-users should not need to define their own instances.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  happens in the scope of a parameter, you must make sure the string is chosen to keep it unique per parameter value. For instance, if you have:  bar :: SInteger -> SInteger -> SInteger bar k = smtFunction "bar" (x -> x+k) -- Note the capture of k!  and you call bar 2 and bar 3, you *will* get the same SMTLib function. Obviously this is unsound. The reason is that the parameter value isn't captured by the name. In general, you should simply not do this, but if you must, have a concrete argument to make sure you can create a unique name. Something like:  bar :: String -> SInteger -> SInteger -> SInteger bar tag k = smtFunction ("bar_" ++ tag) (x -> x+k) -- Tag should make the name unique! Then, make sure you use  bar "two" 2 and  bar "three" 3 etc. to preserve the invariant.Note that this is a design choice, to keep function creation as easy to use as possible. SBV could've made  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 . return a monadic result, please get in touch!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 issuesUsually 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 checkSat4The solver will complain about the unknown constant f (Int).7A workaround of this is to explicit register them with : runSMTWith z3 $ do let f = uninterpret "f" :: SInteger -> SInteger registerUISMTFunction f query $ do constrain $ \(Forall (b :: SInteger)) -> f b .== f b checkSatSee  -https://github.com/LeventErkok/sbv/issues/711 for more info.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.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.Most generalized form of uninterpretation, this function should not be needed by end-user-code, but is rather useful for the library development.A synonym for 8. Allows us to create variables without having to call 7 explicitly, i.e., without being in the symbolic monad.4Render an uninterpeted value as an SMTLib definition Not exported. Used only in  . Instances are provided for the generic representations of product types where each element is Mergeable.)Symbolic conditionals are modeled by the  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  instance may be automatically derived for a custom data-type with a single constructor where the type of each field is an instance of ?, such as a record of symbolic values. Users only need to add  and  to the deriving clause for the data-type. See m for an example and an illustration of what the instance would look like if written by hand. The function  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   function.>Minimal complete definition: None, if the type is instance of Generic . Otherwise . Note that most types subject to merging are likely to be trivial instances of Generic.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.Total indexing operation. select xs default index is intuitively the same as  xs !! index, except it evaluates to default if index underflows/overflows.The  class captures the essence of division. Unfortunately we cannot use Haskell's  class since the  and  superclasses are not implementable for symbolic bit-vectors. However,   and  " both make perfect sense, and the  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  0 = (0, x) x  0 = (0, x) 5Note that our instances implement this law even when x is 0 itself.NB.   truncates toward zero, while  $ truncates toward negative infinity.(C code generation of division operationsIn the case of division or modulo of a minimal signed value (e.g. -128 for ) 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.;Finite bit-length symbolic values. Essentially the same as , but further leaves out . 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: . Bit size.:Least significant bit of a word, always stored at index 0.Most significant bit of a word, always stored at the last position.,Big-endian blasting of a word into its bits./Little-endian blasting of a word into its bits.4Reconstruct from given bits, given in little-endian.4Reconstruct from given bits, given in little-endian.Replacement for  , returning  instead of . Variant of 2, where we want to extract multiple bit positions. Variant of  , returning a symbolic value. A combo of   and  %, when the bit to be set is symbolic. Variant of  when the index is symbolic. If the index it out-of-bounds, then the result is underspecified.Full adder, returns carry-out from the addition. Only for unsigned quantities.Full multiplier, returns both high and low-order bits. Only for unsigned quantities.9Count leading zeros in a word, big-endian interpretation.:Count trailing zeros in a word, big-endian interpretation.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 ,  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 / class, except ranging over symbolic instances.!Symbolic Comparisons. Similar to  , we cannot implement Haskell's + class since there is no way to return an  1 value from a symbolic comparison. Furthermore,  requires  to implement if-then-else, for the benefit of implementing symbolic versions of   and   functions.Symbolic less than.Symbolic less than or equal to.Symbolic greater than."Symbolic greater than or equal to.Symbolic minimum.Symbolic maximum. Is the value within the allowed  inclusive range?Identify tuple like things. Note that there are no methods, just instances to control type inference Generate a variable, named Generate an unnamed variable$Generate a finite constant bitvector'Convert a constant to an integral valueGeneralization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of Generalization of  Generalization of Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of  Generalization of !Generalization of !Generalization of !Generalization of !Generalization of !Generalization of !Generalization of !Generalization of Generalization of 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.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 . which is good for printing counter-examples.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  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.9Observe the value of an expression, unconditionally. See  for a generalized version.Zero extend a bit-vector.Sign extend a bit-vector.Returns 1 if the boolean is , otherwise 0.!+Lift a pseudo-boolean op, performing checks if at most k of the input arguments are  if at least k of the input arguments are  if exactly k of the input arguments are  if the sum of coefficients for  elements is at most k. Generalizes . if the sum of coefficients for  elements is at least k. Generalizes . if the sum of coefficients for  elements is exactly least k. Useful for coding exactly K-of-N2 constraints, and in particular mutex constraints.  if there is at most one set bit  if there is exactly one set bit!Convert a concrete pseudo-boolean to given int; converting to integer!:Predicate for optimizing word operations like (+) and (*).!:Predicate for optimizing word operations like (+) and (*). Symbolic exponentiation using bit blasting and repeated squaring.N.B. The exponent must be unsigned/bounded if symbolic. Signed exponents will be rejected.!&Lift a 1 arg FP-op, using sRNE default!7Lift a float/double unary function, only over constants!8Lift a float/double binary function, only over constants!Lift an sreal unary function!Lift an sreal binary function ?Conversion between integral-symbolic values, akin to Haskell's !!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. Generalization of !6, when the shift-amount is symbolic. Since Haskell's ! only takes an  as the shift amount, it cannot be used when we have a symbolic amount to shift with. Generalization of !6, when the shift-amount is symbolic. Since Haskell's ! only takes an  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   for a variant that explicitly uses the msb as the sign bit, even for unsigned underlying types. Arithmetic shift-right with a symbolic unsigned shift amount. This is equivalent to   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. Generalization of !6, when the shift-amount is symbolic. Since Haskell's ! only takes an  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. 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   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  . Generalization of !6, when the shift-amount is symbolic. Since Haskell's ! only takes an  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. An implementation of rotate-right, using a barrel shifter like design. See comments for   for details.!*Helper function for use in enum operations =Does the concrete positive number n divide the given integer? Lift  2 to symbolic words. Division by 0 is defined s.t. x/0 = 0; which holds even when x is 0 itself. Lift  2 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) Euclidian division and modulus. Euclidian division. Euclidian modulus. $If-then-else. This is by definition  with both branches forced. This is typically the desired behavior, but also see   should you need more laziness. 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. Symbolic assert. Check that the given boolean condition is always  in the given path. The optional first argument can be used to provide call-stack info via GHC's location facilities.!#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 2 when needed; which should be rare to start with.)!?Construct a useful error message if we hit an unmergeable case.!6Merge concrete values that can be checked for equality Not exported. Symbolic merge using the generic representation provided by . Generalization of  Generalization of  Generalization of  1Quick 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.!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 ! 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. Reading a value from an array. 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. Using a lambda as an array. Turn a constant association-list and a default into a symbolic array.!Symbolic computations provide a context for writing symbolic programs.!Using   or 6 on non-concrete values will result in an error. Use  or  instead.!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.! We give a specific instance for , because the underlying floating-point type doesn't support fromRational directly. The overlap with the above instance is unfortunate.!Define Floating instance on SBV's; only for base types that are already floating; i.e., , , and *. (See the separate definition below for +.) Note that unless you use delta-sat via  on , 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 ! for ,  and .!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.!SymVal for 8-tuples!SymVal for 7-tuples!SymVal for 6-tuples!SymVal for 5-tuples!SymVal for 4-tuples!SymVal for 3-tuples!SymVal for 2-tuples!SymVal for 0-tuple (i.e., unit)! instance for ! instance for ! instance for ! instance for ! instance for ! instance for !If comparison is over something SMTLib can handle, just translate it. Otherwise desugar.! Optimizing ! Optimizing Input, of size nOutput, of size m. n < m must holdInput, of size nOutput, of size m. n < m must hold*         !!  !       !          !                    !          !!!   !!!         !!   -(c) Joel Burget Levent ErkokBSD3erkokl@gmail.com experimentalNone 1j! tuple @(Integer, Bool, (String, Char)) (untuple p) .== pQ.E.D. Constructing a tuple from its parts. Forms an isomorphism pair with  :prove $ \p -> untuple @(Integer, Bool, (String, Char)) (tuple p) .== pQ.E.D.! The class !4 captures the notion that a type has a certain field! Field labels Field access, inspired by the lens library. This is merely reverse application, but allows us to write things like  (1, 2)^._1 which is likely to be familiar to most Haskell programmers out there. Note that this is precisely equivalent to  _1 (1, 2)', but perhaps it reads a little nicer. Swap the elements of a 2-tuple!Dynamic interface to exporting tuples, this function is not exported on purpose; use it only via the field functions  ,  , etc. Access the 1st element of an STupleN,  2 <= N <= 8 . Also see  . Access the 2nd element of an STupleN,  2 <= N <= 8 . Also see  . Access the 3rd element of an STupleN,  3 <= N <= 8 . Also see  . Access the 4th element of an STupleN,  4 <= N <= 8 . Also see  . Access the 5th element of an STupleN,  5 <= N <= 8 . Also see  . Access the 6th element of an STupleN,  6 <= N <= 8 . Also see  . Access the 7th element of an STupleN,  7 <= N <= 8 . Also see  . Access the 8th element of an STupleN,  8 <= N <= 8 . Also see  .   (c) Levent ErkokBSD3erkokl@gmail.com experimentalNonend A symbolic tree containing values of type e, indexed by elements of type i. Note that these are full-trees, and their their shapes remain constant. There is no API provided that can change the shape of the tree. These structures are useful when dealing with data-structures that are indexed with symbolic values where access time is important.  7 structures provide logarithmic time reads and writes. Reading a value. We bit-blast the index and descend down the full tree according to bit-values. Writing a value, similar to how reads are done. The important thing is that the tree representation keeps updates to a minimum. Construct the fully balanced initial tree using the given values.  (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 1K Implements polynomial addition, multiplication, division, and modulus operations over GF(2^n). NB. Similar to , division by 0 is interpreted as follows: x   0 = (0, x)for all x (including 0)Minimal complete definition:  ,  ,  Given bit-positions to be set, create a polynomial For instance polynomial [0, 1, 3] :: SWord8will evaluate to 11, since it sets the bits 0, 1, and 31. Mathematicians would write this polynomial as  x^3 + x + 1. And in fact,   will show it like that. Add two polynomials in GF(2^n). Multiply two polynomials in GF(2^n), and reduce it by the irreducible specified by the polynomial as specified by coefficients of the third argument. Note that the third argument is specifically left in this form as it is usually in GF(2^(n+1)), which is not available in our formalism. (That is, we would need SWord9 for SWord8 multiplication, etc.) Also note that we do not support symbolic irreducibles, which is a minor shortcoming. (Most GF's will come with fixed irreducibles, so this should not be a problem in practice.)Passing [] for the third argument will multiply the polynomials and then ignore the higher bits that won't fit into the resulting size. Divide two polynomials in GF(2^n), see above note for division by 0. Compute modulus of two polynomials in GF(2^n), see above note for modulus by 0. %Division and modulus packed together. Display a polynomial like a mathematician would (over the monomial x), with a type. Display a polynomial like a mathematician would (over the monomial x), the first argument controls if the final type is shown as well.!Pretty print as a polynomial Add two polynomials Run down a boolean condition over two lists. Note that this is different than zipWith as shorter list is assumed to be filled with sFalse at the end (i.e., zero-bits); which nicely pads it when considered as an unsigned number in little-endian form.!Multiply two polynomials and reduce by the third (concrete) irreducible, given by its coefficients. See the remarks for the   function for this design choice 8Compute modulus/remainder of polynomials on bit-vectors. (Compute CRCs over bit-vectors. The call  crcBV n m p" computes the CRC of the message m with respect to polynomial p. The inputs are assumed to be blasted big-endian. The number n5 specifies how many bits of CRC is needed. Note that n+ is actually the degree of the polynomial p, and thus it seems redundant to pass it in. However, in a typical proof context, the polynomial can be symbolic, so we cannot compute the degree easily. While this can be worked-around by generating code that accounts for all possible degrees, the resulting code would be unnecessarily big and complicated, and much harder to reason with. (Also note that a CRC is just the remainder from the polynomial division, but this routine is much faster in practice.)NB. The nth bit of the polynomial p must be set for the CRC to be computed correctly. Note that the polynomial argument p will not even have this bit present most of the time, as it will typically contain bits 0 through n-13 as usual in the CRC literature. The higher order nth bit is simply assumed to be set, as it does not make sense to use a polynomial of a lesser degree. This is usually not a problem since CRC polynomials are designed and expressed this way.NB. The literature on CRC's has many variants on how CRC's are computed. We follow the following simple procedure:Extend the message m by adding n 0 bits on the right+Divide the polynomial thus obtained by the pThe remainder is the CRC value.There are many variants on final XOR's, reversed polynomials etc., so it is essential to double check you use the correct  algorithm. Compute CRC's over polynomials, i.e., symbolic words. The first 0 argument plays the same role as the one in the   function.       (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 1 A class of checked-arithmetic operations. These follow the usual arithmetic, except make calls to  to ensure no overflow/underflow can occur. Use them in conjunction with " to ensure no overflow can happen. 3Detecting overflow. Each function here will return  if the result will not fit in the target type, i.e., if it overflows or underflows. Bit-vector addition. Unsigned addition can only overflow. Signed addition can underflow and overflow.A tell tale sign of unsigned addition overflow is when the sum is less than minimum of the arguments.>prove $ \x y -> bvAddO x (y::SWord16) .<=> x + y .< x `smin` yQ.E.D. Bit-vector subtraction. Unsigned subtraction can only underflow. Signed subtraction can underflow and overflow. Bit-vector multiplication. Unsigned multiplication can only overflow. Signed multiplication can underflow and overflow. Bit-vector division. Unsigned division neither underflows nor overflows. Signed division can only overflow. In fact, for each signed bitvector type, there's precisely one pair that overflows, when x is minBound and y is -1:&allSat $ \x y -> x `bvDivO` (y::SInt8) Solution #1: s0 = -128 :: Int8 s1 = -1 :: Int8This is the only solution. Bit-vector negation. Unsigned negation neither underflows nor overflows. Signed negation can only overflow, when the argument is minBound:4prove $ \x -> x .== minBound .<=> bvNegO (x::SInt16)Q.E.D.!Check all true!.Are all the bits between a b (inclusive) zero?!-Are all the bits between a b (inclusive) one? Detecting underflow/overflow conditions for casting between bit-vectors. The first output is the result, the second component itself is a pair with the first boolean indicating underflow and the second indicating overflow.:sFromIntegralO (256 :: SInt16) :: (SWord8, (SBool, SBool))(0 :: SWord8,(False,True))9sFromIntegralO (-2 :: SInt16) :: (SWord8, (SBool, SBool))(254 :: SWord8,(True,False))8sFromIntegralO (2 :: SInt16) :: (SWord8, (SBool, SBool))(2 :: SWord8,(False,False))prove $ \x -> sFromIntegralO (x::SInt32) .== (sFromIntegral x :: SInteger, (sFalse, sFalse))Q.E.D.)As the last example shows, converting to - never underflows or overflows for any value.  Version of   that has calls to > for checking no overflow/underflow can happen. Use it with a  call. signedMulOverflow: Checking if a signed bitvector multiplication can overflow. In general you should simply use   for checking signed multiplication overflow for bit-vectors. This is a function supported by SMTLib. Unfortunately, individual implementations have different performance characteristics. For instance, bitwuzla has a fairly performant implementation of this, but z3 does not. (At least not as of August 2024.) In cases where you can't use bitwuzla, you can use this implementation which has better performance.      -(c) Joel Burget Levent ErkokBSD3erkokl@gmail.com experimentalNone"# Length of a string.sat $ \s -> length s .== 2Satisfiable. Model: s0 = "BA" :: Stringsat $ \s -> length s .< 0 Unsatisfiable=prove $ \s1 s2 -> length s1 + length s2 .== length (s1 ++ s2)Q.E.D.   s is True iff the string is empty(prove $ \s -> null s .<=> length s .== 0Q.E.D."prove $ \s -> null s .<=> s .== ""Q.E.D.   returns the head of a string. Unspecified if the string is empty.&prove $ \c -> head (singleton c) .== cQ.E.D.   returns the tail of a string. Unspecified if the string is empty.-prove $ \h s -> tail (singleton h ++ s) .== sQ.E.D.prove $ \s -> length s .> 0 .=> length (tail s) .== length s - 1Q.E.D.prove $ \s -> sNot (null s) .=> singleton (head s) ++ tail s .== sQ.E.D. @  returns the pair of the first character and tail. Unspecified if the string is empty.   returns all but the last element of the list. Unspecified if the string is empty.-prove $ \c t -> init (t ++ singleton c) .== tQ.E.D.   c is the string of length 1 that contains the only character whose value is the 8-bit value c.7prove $ \c -> c .== literal 'A' .=> singleton c .== "A"Q.E.D.(prove $ \c -> length (singleton c) .== 1Q.E.D.   s offset. Substring of length 1 at offset in s*. Unspecified if offset is out of bounds.prove $ \s1 s2 -> strToStrAt (s1 ++ s2) (length s1) .== strToStrAt s2 0Q.E.D.sat $ \s -> length s .>= 2 .&& strToStrAt s 0 ./= strToStrAt s (length s - 1)Satisfiable. Model: s0 = "AB" :: String   s i' is the 8-bit value stored at location i). Unspecified if index is out of bounds.prove $ \i -> i .>= 0 .&& i .<= 4 .=> "AAAAA" `strToCharAt` i .== literal 'A'Q.E.D. Short cut for    cs is the string of length |cs| containing precisely those characters. Note that there is no corresponding function explode:, since we wouldn't know the length of a symbolic string.8prove $ \c1 c2 c3 -> length (implode [c1, c2, c3]) .== 3Q.E.D.prove $ \c1 c2 c3 -> map (strToCharAt (implode [c1, c2, c3])) (map literal [0 .. 2]) .== [c1, c2, c3]Q.E.D. $Prepend an element, the traditional cons. Append an element Empty string. This value has the property that it's the only string with length 0:+prove $ \l -> length l .== 0 .<=> l .== nilQ.E.D. "Concatenate two strings. See also  . Short cut for  .sat $ \x y z -> length x .== 5 .&& length y .== 1 .&& x ++ y ++ z .== "Hello world!"Satisfiable. Model: s0 = "Hello" :: String s1 = " " :: String s2 = "world!" :: String   sub s. Does s contain the substring sub?4prove $ \s1 s2 s3 -> s2 `isInfixOf` (s1 ++ s2 ++ s3)Q.E.D.prove $ \s1 s2 -> s1 `isInfixOf` s2 .&& s2 `isInfixOf` s1 .<=> s1 .== s2Q.E.D.   pre s. Is pre a prefix of s?,prove $ \s1 s2 -> s1 `isPrefixOf` (s1 ++ s2)Q.E.D.prove $ \s1 s2 -> s1 `isPrefixOf` s2 .=> subStr s2 0 (length s1) .== s1Q.E.D.   suf s. Is suf a suffix of s?,prove $ \s1 s2 -> s2 `isSuffixOf` (s1 ++ s2)Q.E.D.prove $ \s1 s2 -> s1 `isSuffixOf` s2 .=> subStr s2 (length s2 - length s1) (length s1) .== s1Q.E.D.   len s. Corresponds to Haskell's   on symbolic-strings.3prove $ \s i -> i .>= 0 .=> length (take i s) .<= iQ.E.D.   len s. Corresponds to Haskell's   on symbolic-strings..prove $ \s i -> length (drop i s) .<= length sQ.E.D.*prove $ \s i -> take i s ++ drop i s .== sQ.E.D.   s offset len is the substring of s at offset offset with length len. This function is under-specified when the offset is outside the range of positions in s or len is negative or  offset+len exceeds the length of s.prove $ \s i -> i .>= 0 .&& i .< length s .=> subStr s 0 i ++ subStr s i (length s - i) .== sQ.E.D.+sat $ \i j -> subStr "hello" i j .== "ell"Satisfiable. Model: s0 = 1 :: Integer s1 = 3 :: Integer)sat $ \i j -> subStr "hell" i j .== "no" Unsatisfiable   s src dst". Replace the first occurrence of src by dst in sprove $ \s -> replace "hello" s "world" .== "world" .=> s .== "hello"Q.E.D.prove $ \s1 s2 s3 -> length s2 .> length s1 .=> replace s1 s2 s3 .== s1Q.E.D.   s sub. Retrieves first position of sub in s, -1- if there are no occurrences. Equivalent to   s sub 0.prove $ \s1 s2 -> length s2 .> length s1 .=> indexOf s1 s2 .== -1Q.E.D.   s sub offset. Retrieves first position of sub at or after offset in s, -1 if there are no occurrences.9prove $ \s sub -> offsetIndexOf s sub 0 .== indexOf s subQ.E.D.prove $ \s sub i -> i .>= length s .&& length sub .> 0 .=> offsetIndexOf s sub i .== -1Q.E.D.prove $ \s sub i -> i .> length s .=> offsetIndexOf s sub i .== -1Q.E.D.   s reverses the string. >>> sat $ s -> reverse s .== "abc" Satisfiable. Model: s0 = "cba" :: String >>> prove $ s -> reverse s .== "" . = null s Q.E.D.   s%. Retrieve integer encoded by string s (ground rewriting only). Note that by definition this function only works when s only contains digits, that is, if it encodes a natural number. Otherwise, it returns '-1'.prove $ \s -> let n = strToNat s in length s .== 1 .=> (-1) .<= n .&& n .<= 9Q.E.D.   i%. Retrieve string encoded by integer i (ground rewriting only). Again, only naturals are supported, any input that is not a natural number produces empty string, even though we take an integer as an argument.5prove $ \i -> length (natToStr i) .== 3 .=> i .<= 999Q.E.D.!#Lift a unary operator over strings.!$Lift a binary operator over strings.!%Lift a ternary operator over strings.!!Concrete evaluation for unary ops!"Concrete evaluation for binary ops!#Concrete evaluation for ternary ops!%Is the string concretely known empty?    (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone  Empty set.empty :: SSet Integer{} :: {SInteger}  Full set.full :: SSet IntegerU :: {SInteger}Note that the universal set over a type is represented by the letter U.  Synonym for  . Singleton list.singleton 2 :: SSet Integer{2} :: {SInteger} Conversion from a list.fromList ([] :: [Integer]){} :: {SInteger}fromList [1,2,3]{1,2,3} :: {SInteger}fromList [5,5,5,12,12,3]{3,5,12} :: {SInteger}  Complement.+empty .== complement (full :: SSet Integer)True2Complementing twice gets us back the original set:?prove $ \(s :: SSet Integer) -> complement (complement s) .== sQ.E.D. Insert an element into a set.Insertion is order independent:prove $ \x y (s :: SSet Integer) -> x `insert` (y `insert` s) .== y `insert` (x `insert` s)Q.E.D.5Deletion after insertion is not necessarily identity:prove $ \x (s :: SSet Integer) -> x `delete` (x `insert` s) .== sFalsifiable. Counter-example: s0 = 2 :: Integer s1 = U :: {Integer}But the above is true if the element isn't in the set to start with:prove $ \x (s :: SSet Integer) -> x `notMember` s .=> x `delete` (x `insert` s) .== sQ.E.D.'Insertion into a full set does nothing:6prove $ \x -> insert x full .== (full :: SSet Integer)Q.E.D. Delete an element from a set.Deletion is order independent:prove $ \x y (s :: SSet Integer) -> x `delete` (y `delete` s) .== y `delete` (x `delete` s)Q.E.D.5Insertion after deletion is not necessarily identity:prove $ \x (s :: SSet Integer) -> x `insert` (x `delete` s) .== sFalsifiable. Counter-example: s0 = 2 :: Integer s1 = U - {2} :: {Integer}But the above is true if the element is in the set to start with:prove $ \x (s :: SSet Integer) -> x `member` s .=> x `insert` (x `delete` s) .== sQ.E.D.(Deletion from an empty set does nothing:8prove $ \x -> delete x empty .== (empty :: SSet Integer)Q.E.D. Test for membership.2prove $ \x -> x `member` singleton (x :: SInteger)Q.E.D.;prove $ \x (s :: SSet Integer) -> x `member` (x `insert` s)Q.E.D./prove $ \x -> x `member` (full :: SSet Integer)Q.E.D. Test for non-membership.prove $ \x -> x `notMember` observe "set" (singleton (x :: SInteger))Falsifiable. Counter-example: set = {0} :: {Integer} s0 = 0 :: Integer>prove $ \x (s :: SSet Integer) -> x `notMember` (x `delete` s)Q.E.D.3prove $ \x -> x `notMember` (empty :: SSet Integer)Q.E.D. Is this the empty set?null (empty :: SSet Integer)True9prove $ \x -> null (x `delete` singleton (x :: SInteger))Q.E.D.#prove $ null (full :: SSet Integer) FalsifiableNote how we have to call  in the last case since dealing with infinite sets requires a call to the solver and cannot be constant folded.  Synonym for . Is this the full set?&prove $ isFull (empty :: SSet Integer) Falsifiableprove $ \x -> isFull (observe "set" (x `delete` (full :: SSet Integer)))Falsifiable. Counter-example: set = U - {2} :: {Integer} s0 = 2 :: IntegerisFull (full :: SSet Integer)TrueNote how we have to call  in the first case since dealing with infinite sets requires a call to the solver and cannot be constant folded.  Synonym for .  Subset test.1prove $ empty `isSubsetOf` (full :: SSet Integer)Q.E.D.?prove $ \x (s :: SSet Integer) -> s `isSubsetOf` (x `insert` s)Q.E.D.?prove $ \x (s :: SSet Integer) -> (x `delete` s) `isSubsetOf` sQ.E.D. Proper subset test.7prove $ empty `isProperSubsetOf` (full :: SSet Integer)Q.E.D.prove $ \x (s :: SSet Integer) -> s `isProperSubsetOf` (x `insert` s)Falsifiable. Counter-example: s0 = 2 :: Integer s1 = U :: {Integer}prove $ \x (s :: SSet Integer) -> x `notMember` s .=> s `isProperSubsetOf` (x `insert` s)Q.E.D.prove $ \x (s :: SSet Integer) -> (x `delete` s) `isProperSubsetOf` sFalsifiable. Counter-example: s0 = 2 :: Integer s1 = U - {2,3} :: {Integer}prove $ \x (s :: SSet Integer) -> x `member` s .=> (x `delete` s) `isProperSubsetOf` sQ.E.D. Disjoint test..disjoint (fromList [2,4,6]) (fromList [1,3])True2disjoint (fromList [2,4,6,8]) (fromList [2,3,5,7])False2disjoint (fromList [1,2]) (fromList [1,2,3,4])False9prove $ \(s :: SSet Integer) -> s `disjoint` complement sQ.E.D./allSat $ \(s :: SSet Integer) -> s `disjoint` s Solution #1: s0 = {} :: {Integer}This is the only solution.The last example is particularly interesting: The empty set is the only set where   is not reflexive!Note that disjointness of a set from its complement is guaranteed by the fact that all types are inhabited; an implicit assumption we have in classic logic which is also enjoyed by Haskell due to the presence of bottom! Union.union (fromList [1..10]) (fromList [5..15]) .== (fromList [1..15] :: SSet Integer)True=prove $ \(a :: SSet Integer) b -> a `union` b .== b `union` aQ.E.D.prove $ \(a :: SSet Integer) b c -> a `union` (b `union` c) .== (a `union` b) `union` cQ.E.D.7prove $ \(a :: SSet Integer) -> a `union` full .== fullQ.E.D.5prove $ \(a :: SSet Integer) -> a `union` empty .== aQ.E.D.?prove $ \(a :: SSet Integer) -> a `union` complement a .== fullQ.E.D. Unions. Equivalent to !    .-prove $ unions [] .== (empty :: SSet Integer)Q.E.D.  Intersection.intersection (fromList [1..10]) (fromList [5..15]) .== (fromList [5..10] :: SSet Integer)Trueprove $ \(a :: SSet Integer) b -> a `intersection` b .== b `intersection` aQ.E.D.prove $ \(a :: SSet Integer) b c -> a `intersection` (b `intersection` c) .== (a `intersection` b) `intersection` cQ.E.D.;prove $ \(a :: SSet Integer) -> a `intersection` full .== aQ.E.D.prove $ \(a :: SSet Integer) -> a `intersection` empty .== emptyQ.E.D.prove $ \(a :: SSet Integer) -> a `intersection` complement a .== emptyQ.E.D.prove $ \(a :: SSet Integer) b -> a `disjoint` b .=> a `intersection` b .== emptyQ.E.D. Intersections. Equivalent to !    . Note that Haskell's  does not support this operation as it does not have a way of representing universal sets.3prove $ intersections [] .== (full :: SSet Integer)Q.E.D.  Difference.>prove $ \(a :: SSet Integer) -> empty `difference` a .== emptyQ.E.D.:prove $ \(a :: SSet Integer) -> a `difference` empty .== aQ.E.D.prove $ \(a :: SSet Integer) -> full `difference` a .== complement aQ.E.D.:prove $ \(a :: SSet Integer) -> a `difference` a .== emptyQ.E.D.  Synonym for .    (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone Construct a symbolic rational from a given numerator and denominator. Note that it is not possible to deconstruct a rational by taking numerator and denominator fields, since we do not represent them canonically. (This is due to the fact that SMTLib has no functions to compute the GCD. One can use the maximization engine to compute the GCD of numbers, but not as a function.)   -(c) Joel Burget Levent ErkokBSD3erkokl@gmail.com experimentalNonei  The symbolic .sNothing :: SMaybe IntegerNothing :: SMaybe Integer 'Check if the symbolic value is nothing.&isNothing (sNothing :: SMaybe Integer)True"isNothing (sJust (literal "nope"))False  Construct an SMaybe a from an SBV a.sJust (3 :: SInteger)Just 3 :: SMaybe Integer +Check if the symbolic value is not nothing.#isJust (sNothing :: SMaybe Integer)FalseisJust (sJust (literal "yep"))True,prove $ \x -> isJust (sJust (x :: SInteger))Q.E.D. Return the value of an optional value. The default is returned if Nothing. Compare to  .(fromMaybe 2 (sNothing :: SMaybe Integer) 2 :: SInteger'fromMaybe 2 (sJust 5 :: SMaybe Integer) 5 :: SInteger fromMaybe x (sNothing :: SMaybe Integer) .== xQ.E.D.?prove $ \x -> fromMaybe (x+1) (sJust x :: SMaybe Integer) .== xQ.E.D. Return the value of an optional value. The behavior is undefined if passed Nothing, i.e., it can return any value. Compare to  .fromJust (sJust (literal 'a')) 'a' :: SChar1prove $ \x -> fromJust (sJust x) .== (x :: SChar)Q.E.D..sat $ \x -> x .== (fromJust sNothing :: SChar)Satisfiable. Model: s0 = 'A' :: CharNote how we get a satisfying assignment in the last case: The behavior is unspecified, thus the SMT solver picks whatever satisfies the constraints, if there is one.  Construct an SMaybe a from a  Maybe (SBV a). liftMaybe (Just (3 :: SInteger))Just 3 :: SMaybe Integer%liftMaybe (Nothing :: Maybe SInteger)Nothing :: SMaybe Integer  Map over the ! side of a .?prove $ \x -> fromJust (map (+1) (sJust x)) .== x+(1::SInteger)Q.E.D.,let f = uninterpret "f" :: SInteger -> SBool-prove $ \x -> map f (sJust x) .== sJust (f x)Q.E.D.map f sNothing .== sNothingTrue Map over two maybe values. Case analysis for symbolic s. If the value  #, return the default value; if it  , apply the function.*maybe 0 (`sMod` 2) (sJust (3 :: SInteger)) 1 :: SInteger/maybe 0 (`sMod` 2) (sNothing :: SMaybe Integer) 0 :: SInteger,let f = uninterpret "f" :: SInteger -> SBool+prove $ \x d -> maybe d f (sJust x) .== f xQ.E.D.&prove $ \d -> maybe d f sNothing .== dQ.E.D. Custom  instance over  -(c) Joel Burget Levent ErkokBSD3erkokl@gmail.com experimentalNone#M. Length of a list.,sat $ \(l :: SList Word16) -> length l .== 2Satisfiable. Model: s0 = [0,0] :: [Word16]+sat $ \(l :: SList Word16) -> length l .< 0 Unsatisfiableprove $ \(l1 :: SList Word16) (l2 :: SList Word16) -> length l1 + length l2 .== length (l1 ++ l2)Q.E.D.   s is True iff the list is empty:prove $ \(l :: SList Word16) -> null l .<=> length l .== 0Q.E.D.4prove $ \(l :: SList Word16) -> null l .<=> l .== []Q.E.D.   returns the first element of a list. Unspecified if the list is empty.4prove $ \c -> head (singleton c) .== (c :: SInteger)Q.E.D.  > returns the tail of a list. Unspecified if the list is empty.;prove $ \(h :: SInteger) t -> tail (singleton h ++ t) .== tQ.E.D.prove $ \(l :: SList Integer) -> length l .> 0 .=> length (tail l) .== length l - 1Q.E.D.prove $ \(l :: SList Integer) -> sNot (null l) .=> singleton (head l) ++ tail l .== lQ.E.D.   returns the pair of the head and tail. Unspecified if the list is empty.   returns all but the last element of the list. Unspecified if the list is empty.;prove $ \(h :: SInteger) t -> init (t ++ singleton h) .== tQ.E.D.   x6 is the list of length 1 that contains the only value x.4prove $ \(x :: SInteger) -> head (singleton x) .== xQ.E.D.6prove $ \(x :: SInteger) -> length (singleton x) .== 1Q.E.D.   l offset. List of length 1 at offset in l). Unspecified if index is out of bounds.prove $ \(l1 :: SList Integer) l2 -> listToListAt (l1 ++ l2) (length l1) .== listToListAt l2 0Q.E.D.sat $ \(l :: SList Word16) -> length l .>= 2 .&& listToListAt l 0 ./= listToListAt l (length l - 1)Satisfiable. Model: s0 = [0,64] :: [Word16]   l i! is the value stored at location i8, starting at 0. Unspecified if index is out of bounds.prove $ \i -> i `inRange` (0, 4) .=> [1,1,1,1,1] `elemAt` i .== (1::SInteger)Q.E.D. Short cut for    es is the list of length |es| containing precisely those elements. Note that there is no corresponding function explode8, since we wouldn't know the length of a symbolic list.prove $ \(e1 :: SInteger) e2 e3 -> length (implode [e1, e2, e3]) .== 3Q.E.D.prove $ \(e1 :: SInteger) e2 e3 -> P.map (elemAt (implode [e1, e2, e3])) (P.map literal [0 .. 2]) .== [e1, e2, e3]Q.E.D. $Prepend an element, the traditional cons. Append an element Empty list. This value has the property that it's the only list with length 0:>prove $ \(l :: SList Integer) -> length l .== 0 .<=> l .== nilQ.E.D. Append two lists.sat $ \x y z -> length x .== 5 .&& length y .== 1 .&& x ++ y ++ z .== [1 .. 12]Satisfiable. Model:$ s0 = [1,2,3,4,5] :: [Integer]$ s1 = [6] :: [Integer]$ s2 = [7,8,9,10,11,12] :: [Integer]   e l. Does l contain the element e?   e l. Does l not contain the element e?   sub l. Does l contain the subsequence sub?prove $ \(l1 :: SList Integer) l2 l3 -> l2 `isInfixOf` (l1 ++ l2 ++ l3)Q.E.D.prove $ \(l1 :: SList Integer) l2 -> l1 `isInfixOf` l2 .&& l2 `isInfixOf` l1 .<=> l1 .== l2Q.E.D.   pre l. Is pre a prefix of l??prove $ \(l1 :: SList Integer) l2 -> l1 `isPrefixOf` (l1 ++ l2)Q.E.D.prove $ \(l1 :: SList Integer) l2 -> l1 `isPrefixOf` l2 .=> subList l2 0 (length l1) .== l1Q.E.D.   suf l. Is suf a suffix of l?>prove $ \(l1 :: SList Word16) l2 -> l2 `isSuffixOf` (l1 ++ l2)Q.E.D.prove $ \(l1 :: SList Word16) l2 -> l1 `isSuffixOf` l2 .=> subList l2 (length l2 - length l1) (length l1) .== l1Q.E.D.   len l. Corresponds to Haskell's   on symbolic lists.prove $ \(l :: SList Integer) i -> i .>= 0 .=> length (take i l) .<= iQ.E.D.   len s. Corresponds to Haskell's   on symbolic-lists.prove $ \(l :: SList Word16) i -> length (drop i l) .<= length lQ.E.D. take i l ++ drop i l .== lQ.E.D.   s offset len is the sublist of s at offset offset with length len. This function is under-specified when the offset is outside the range of positions in s or len is negative or  offset+len exceeds the length of s.prove $ \(l :: SList Integer) i -> i .>= 0 .&& i .< length l .=> subList l 0 i ++ subList l i (length l - i) .== lQ.E.D.?sat $ \i j -> subList [1..5] i j .== ([2..4] :: SList Integer)Satisfiable. Model: s0 = 1 :: Integer s1 = 3 :: Integer?sat $ \i j -> subList [1..5] i j .== ([6..7] :: SList Integer) Unsatisfiable   l src dst". Replace the first occurrence of src by dst in sprove $ \l -> replace [1..5] l [6..10] .== [6..10] .=> l .== ([1..5] :: SList Word8)Q.E.D.prove $ \(l1 :: SList Integer) l2 l3 -> length l2 .> length l1 .=> replace l1 l2 l3 .== l1Q.E.D.   l sub. Retrieves first position of sub in l, -1- if there are no occurrences. Equivalent to   l sub 0.prove $ \(l1 :: SList Word16) l2 -> length l2 .> length l1 .=> indexOf l1 l2 .== -1Q.E.D.   l sub offset. Retrieves first position of sub at or after offset in l, -1 if there are no occurrences.prove $ \(l :: SList Int8) sub -> offsetIndexOf l sub 0 .== indexOf l subQ.E.D.prove $ \(l :: SList Int8) sub i -> i .>= length l .&& length sub .> 0 .=> offsetIndexOf l sub i .== -1Q.E.D.prove $ \(l :: SList Int8) sub i -> i .> length l .=> offsetIndexOf l sub i .== -1Q.E.D.   s reverses the sequence.NB. We can define reverse in terms of foldl as: .foldl (soFar elt -> singleton elt ++ soFar) [] But in my experiments, I found that this definition performs worse instead of the recursive definition SBV generates for reverse calls. So we're keeping it intact.>sat $ \(l :: SList Integer) -> reverse l .== literal [3, 2, 1]Satisfiable. Model: s0 = [1,2,3] :: [Integer] reverse l .== [] .<=> null lQ.E.D.   op s# maps the operation on to sequence.map (+1) [1 .. 5 :: Integer][2,3,4,5,6] :: [SInteger]map (+1) [1 .. 5 :: WordN 8][2,3,4,5,6] :: [SWord8]!map singleton [1 .. 3 :: Integer][[1],[2],[3]] :: [[SInteger]]import Data.SBV.Tupleimport GHC.Exts (fromList)map (\t -> t^._1 + t^._2) (fromList [(x, y) | x <- [1..3], y <- [4..6]] :: SList (Integer, Integer))![5,6,7,6,7,8,7,8,9] :: [SInteger]Of course, SBV's   can also be reused in reverse:-sat $ \l -> map (+1) l .== [1,2,3 :: Integer]Satisfiable. Model: s0 = [0,1,2] :: [Integer]   op s maps the operation on to sequence, with the counter given at each element, starting at the given value. In Haskell terms, it is:  mapi :: (Integer -> a -> b) -> Integer -> [a] -> [b] mapi f i xs = zipWith f [i..] xs  Note that   is definable in terms of , with extra coding. The reason why SBV provides this function natively is because it maps to a native function in the underlying solver. So, hopefully it'll perform better in terms being decidable.mapi (+) 10 [1 .. 5 :: Integer][11,13,15,17,19] :: [SInteger]   op base s folds the from the left.foldl (+) 0 [1 .. 5 :: Integer]15 :: SIntegerfoldl (*) 1 [1 .. 5 :: Integer]120 :: SIntegerfoldl (\soFar elt -> singleton elt ++ soFar) ([] :: SList Integer) [1 .. 5 :: Integer][5,4,3,2,1] :: [SInteger]Again, we can use  in the reverse too:sat $ \l -> foldl (\soFar elt -> singleton elt ++ soFar) ([] :: SList Integer) l .== [5, 4, 3, 2, 1 :: Integer]Satisfiable. Model: s0 = [1,2,3,4,5] :: [Integer]   op i base s folds the sequence, with the counter given at each element, starting at the given value. In Haskell terms, it is:  foldli :: (Integer -> b -> a -> b) -> Integer -> b -> [a] -> b foldli f c e xs = foldl (b (i, a) -> f i b a) e (zip [c..] xs) While this function is rather odd looking, it maps directly to the implementation in the underlying solver, and proofs involving it might have better decidability.1foldli (\i b a -> i+b+a) 10 0 [1 .. 5 :: Integer]75 :: SInteger   op base s# folds the sequence from the right.foldr (+) 0 [1 .. 5 :: Integer]15 :: SIntegerfoldr (*) 1 [1 .. 5 :: Integer]120 :: SIntegerfoldr (\elt soFar -> soFar ++ singleton elt) ([] :: SList Integer) [1 .. 5 :: Integer][5,4,3,2,1] :: [SInteger]   op base i s folds the sequence from the right, with the counter given at each element, starting at the given value. This function is provided as a parallel to  .   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.&zip [1..10::Integer] [11..20::Integer][(1,11),(2,12),(3,13),(4,14),(5,15),(6,16),(7,17),(8,18),(9,19),(10,20)] :: [(SInteger, SInteger)]import Data.SBV.Tuplefoldr (+) 0 (map (\t -> t^._1+t^._2::SInteger) (zip [1..10::Integer] [10, 9..1::Integer]))110 :: SInteger   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..zipWith (+) [1..10::Integer] [11..20::Integer]-[12,14,16,18,20,22,24,26,28,30] :: [SInteger]>foldr (+) 0 (zipWith (+) [1..10::Integer] [10, 9..1::Integer])110 :: SInteger Concatenate list of lists.NB. Concat is typically defined in terms of foldr. Here we prefer foldl, since the underlying solver primitive is foldl: Otherwise, we'd induce an extra call to reverse.)concat [[1..3::Integer], [4..7], [8..10]]$[1,2,3,4,5,6,7,8,9,10] :: [SInteger] )Check all elements satisfy the predicate.let isEven x = x `sMod` 2 .== 0&all isEven [2, 4, 6, 8, 10 :: Integer]True)all isEven [2, 4, 6, 1, 8, 10 :: Integer]False Check some element satisfies the predicate. -- >>> let isEven x = x  2 .== 0 >>> any (sNot . isEven) [2, 4, 6, 8, 10 :: Integer] False >>> any isEven [2, 4, 6, 1, 8, 10 :: Integer] True  filter f xs+ filters the list with the given predicate.4filter (\x -> x `sMod` 2 .== 0) [1 .. 10 :: Integer][2,4,6,8,10] :: [SInteger]4filter (\x -> x `sMod` 2 ./= 0) [1 .. 10 :: Integer][1,3,5,7,9] :: [SInteger]!!Lift a unary operator over lists.!"Lift a binary operator over lists.!#Lift a ternary operator over lists.!!Concrete evaluation for unary ops!"Concrete evaluation for binary ops!#Concrete evaluation for ternary ops!#Is the list concretely known empty?' '   -(c) Joel Burget Levent ErkokBSD3erkokl@gmail.com experimentalNone0  Construct an  SEither a b from an SBV asLeft 3 :: SEither Integer BoolLeft 3 :: SEither Integer Bool Return  if the given symbolic value is ,  otherwise(isLeft (sLeft 3 :: SEither Integer Bool)True-isLeft (sRight sTrue :: SEither Integer Bool)False  Construct an  SEither a b from an SBV b%sRight sFalse :: SEither Integer Bool#Right False :: SEither Integer Bool Return  if the given symbolic value is ,  otherwise)isRight (sLeft 3 :: SEither Integer Bool)False.isRight (sRight sTrue :: SEither Integer Bool)True  Construct an  SEither a b from an Either (SBV a) (SBV b),liftEither (Left 3 :: Either SInteger SBool)Left 3 :: SEither Integer Bool1liftEither (Right sTrue :: Either SInteger SBool)"Right True :: SEither Integer Bool Case analysis for symbolic s. If the value  #, apply the first function; if it  , apply the second function.(either (*2) (*3) (sLeft (3 :: SInteger)) 6 :: SInteger)either (*2) (*3) (sRight (3 :: SInteger)) 9 :: SInteger/let f = uninterpret "f" :: SInteger -> SInteger/let g = uninterpret "g" :: SInteger -> SInteger*prove $ \x -> either f g (sLeft x) .== f xQ.E.D.+prove $ \x -> either f g (sRight x) .== g xQ.E.D. "Map over both sides of a symbolic  at the same time/let f = uninterpret "f" :: SInteger -> SInteger/let g = uninterpret "g" :: SInteger -> SInteger4prove $ \x -> fromLeft (bimap f g (sLeft x)) .== f xQ.E.D.6prove $ \x -> fromRight (bimap f g (sRight x)) .== g xQ.E.D. Map over the left side of an /let f = uninterpret "f" :: SInteger -> SIntegerprove $ \x -> first f (sLeft x :: SEither Integer Integer) .== sLeft (f x)Q.E.D.prove $ \x -> first f (sRight x :: SEither Integer Integer) .== sRight xQ.E.D. Map over the right side of an /let f = uninterpret "f" :: SInteger -> SIntegerprove $ \x -> second f (sRight x :: SEither Integer Integer) .== sRight (f x)Q.E.D.prove $ \x -> second f (sLeft x :: SEither Integer Integer) .== sLeft xQ.E.D. Return the value from the left component. The behavior is undefined if passed a right value, i.e., it can return any value.6fromLeft (sLeft (literal 'a') :: SEither Char Integer) 'a' :: SCharprove $ \x -> fromLeft (sLeft x :: SEither Char Integer) .== (x :: SChar)Q.E.D.?sat $ \x -> x .== (fromLeft (sRight 4 :: SEither Char Integer))Satisfiable. Model: s0 = 'A' :: CharNote how we get a satisfying assignment in the last case: The behavior is unspecified, thus the SMT solver picks whatever satisfies the constraints, if there is one. Return the value from the right component. The behavior is undefined if passed a left value, i.e., it can return any value.8fromRight (sRight (literal 'a') :: SEither Integer Char) 'a' :: SCharprove $ \x -> fromRight (sRight x :: SEither Char Integer) .== (x :: SInteger)Q.E.D.sat $ \x -> x .== (fromRight (sLeft (literal 2) :: SEither Integer Char))Satisfiable. Model: s0 = 'A' :: CharNote how we get a satisfying assignment in the last case: The behavior is unspecified, thus the SMT solver picks whatever satisfies the constraints, if there is one. (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone3>#! Conversion to and from floats .Convert from an IEEE74 single precision float. .Convert to an IEEE-754 Single-precision float. .Convert from an IEEE74 double precision float. .Convert to an IEEE-754 Double-precision float. )Convert from an arbitrary floating point. 'Convert to an arbitrary floating point. A class of floating-point (IEEE754) operations, some of which behave differently based on rounding modes. Note that unless the rounding mode is concretely RoundNearestTiesToEven, we will not concretely evaluate these, but rather pass down to the SMT solver. *Compute the floating point absolute value. &Compute the unary negation. Note that 0 - x is not equivalent to -x for floating-point, since -0 and 0 are different.  c `elem` singleton cQ.E.D. prove $ \c -> sNot (c `elem` "")Q.E.D. #Is the character not in the string?4prove $ \c s -> c `elem` s .<=> sNot (c `notElem` s)Q.E.D. The   of a character. *Conversion from an integer to a character.8prove $ \x -> 0 .<= x .&& x .< 256 .=> ord (chr x) .== xQ.E.D.prove $ \x -> chr (ord x) .== xQ.E.D.!Lift a char function to a symbolic version. If the given char is not in the class recognized by predicate, the output is the same as the input. Only works for the Latin1 set, i.e., the first 256 characters. If the given character is outside this range, it's returned unchanged.!Lift a char predicate to a symbolic version. Only works for the Latin1 set, i.e., the first 256 characters. Convert to lower-case. Only works for the Latin1 subset, otherwise returns its argument unchanged.5prove $ \c -> toLowerL1 (toLowerL1 c) .== toLowerL1 cQ.E.D.prove $ \c -> isLowerL1 c .&& c `notElem` "\181\255" .=> toLowerL1 (toUpperL1 c) .== cQ.E.D. Convert to upper-case. Only works for the Latin1 subset, otherwise returns its argument unchanged.5prove $ \c -> toUpperL1 (toUpperL1 c) .== toUpperL1 cQ.E.D.;prove $ \c -> isUpperL1 c .=> toUpperL1 (toLowerL1 c) .== cQ.E.D. Convert a digit to an integer. Works for hexadecimal digits too. If the input isn't a digit, then return -1.prove $ \c -> isDigit c .|| isHexDigit c .=> digitToInt c .>= 0 .&& digitToInt c .<= 15Q.E.D.prove $ \c -> sNot (isDigit c .|| isHexDigit c) .=> digitToInt c .== -1Q.E.D. *Convert an integer to a digit, inverse of  . If the integer is out of bounds, we return the arbitrarily chosen space character. Note that for hexadecimal letters, we return the corresponding lowercase letter.prove $ \i -> i .>= 0 .&& i .<= 15 .=> digitToInt (intToDigit i) .== iQ.E.D.prove $ \i -> i .< 0 .|| i .> 15 .=> digitToInt (intToDigit i) .== -1Q.E.D.prove $ \c -> digitToInt c .== -1 .<=> intToDigit (digitToInt c) .== literal ' 'Q.E.D. Is this a control character? Control characters are essentially the non-printing characters. Only works for the Latin1 subset, otherwise returns . Is this white-space? Only works for the Latin1 subset, otherwise returns . Is this a lower-case character? Only works for the Latin1 subset, otherwise returns .5prove $ \c -> isUpperL1 c .=> isLowerL1 (toLowerL1 c)Q.E.D. Is this an upper-case character? Only works for the Latin1 subset, otherwise returns .0prove $ \c -> sNot (isLowerL1 c .&& isUpperL1 c)Q.E.D. Is this an alphabet character? That is lower-case, upper-case and title-case letters, plus letters of caseless scripts and modifiers letters. Only works for the Latin1 subset, otherwise returns . Is this an alphabetical character or a digit? Only works for the Latin1 subset, otherwise returns .>prove $ \c -> isAlphaNumL1 c .<=> isAlphaL1 c .|| isNumberL1 cQ.E.D. Is this a printable character? Only works for the Latin1 subset, otherwise returns . %Is this an ASCII digit, i.e., one of 0..9 . Note that this is a subset of   (prove $ \c -> isDigit c .=> isNumberL1 cQ.E.D. %Is this an Octal digit, i.e., one of 0..7. !Is this a Hex digit, i.e, one of 0..9, a..f, A..F.-prove $ \c -> isHexDigit c .=> isAlphaNumL1 cQ.E.D. Is this an alphabet character. Only works for the Latin1 subset, otherwise returns .+prove $ \c -> isLetterL1 c .<=> isAlphaL1 cQ.E.D. Is this a mark? Only works for the Latin1 subset, otherwise returns .Note that there are no marks in the Latin1 set, so this function always returns false!prove $ sNot . isMarkL1Q.E.D. Is this a number character? Only works for the Latin1 subset, otherwise returns . Is this a punctuation mark? Only works for the Latin1 subset, otherwise returns . Is this a symbol? Only works for the Latin1 subset, otherwise returns . Is this a separator? Only works for the Latin1 subset, otherwise returns .-prove $ \c -> isSeparatorL1 c .=> isSpaceL1 cQ.E.D. ;Is this an ASCII character, i.e., the first 128 characters. Is this a Latin1 character? *Is this an ASCII Upper-case letter? i.e., A thru Zprove $ \c -> isAsciiUpper c .<=> ord c .>= ord (literal 'A') .&& ord c .<= ord (literal 'Z')Q.E.D.;prove $ \c -> isAsciiUpper c .<=> isAscii c .&& isUpperL1 cQ.E.D. *Is this an ASCII Lower-case letter? i.e., a thru zprove $ \c -> isAsciiLower c .<=> ord c .>= ord (literal 'a') .&& ord c .<= ord (literal 'z')Q.E.D.;prove $ \c -> isAsciiLower c .<=> isAscii c .&& isLowerL1 cQ.E.D.  (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone"L= /Matchable class. Things we can match against a .For instance, you can generate valid-looking phone numbers like this::set -XOverloadedStringslet dig09 = Range '0' '9'let dig19 = Range '1' '9'"let pre = dig19 * Loop 2 2 dig09"let post = dig19 * Loop 3 3 dig09let phone = pre * "-" * post(sat $ \s -> (s :: SString) `match` phoneSatisfiable. Model: s0 = "800-8000" :: String   s r checks whether s! is in the language generated by r. %Match everything, universal acceptor./prove $ \(s :: SString) -> s `match` everythingQ.E.D. "Match nothing, universal rejector.3prove $ \(s :: SString) -> sNot (s `match` nothing)Q.E.D. .Match any character, i.e., strings of length 1prove $ \(s :: SString) -> s `match` anyChar .<=> length s .== 1Q.E.D. A literal regular-expression, matching the given string exactly. Note that with OverloadedStrings extension, you can simply use a Haskell string to mean the same thing, so this function is rarely needed.prove $ \(s :: SString) -> s `match` exactly "LITERAL" .<=> s .== "LITERAL"Q.E.D. #Helper to define a character class.prove $ \(c :: SChar) -> c `match` oneOf "ABCD" .<=> sAny (c .==) (map literal "ABCD")Q.E.D. 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"))/prove $ \c -> c `match` newline .=> isSpaceL1 cQ.E.D. Recognize a tab.tab(str.to.re "\t")2prove $ \c -> c `match` tab .=> c .== literal '\t'Q.E.D.!Lift a char function to a regular expression that recognizes it. .Recognize white-space, but without a new line.prove $ \c -> c `match` whiteSpaceNoNewLine .=> c `match` whiteSpace .&& c ./= literal '\n'Q.E.D. Recognize white space.2prove $ \c -> c `match` whiteSpace .=> isSpaceL1 cQ.E.D. "Recognize a punctuation character.9prove $ \c -> c `match` punctuation .=> isPunctuationL1 cQ.E.D. $Recognize an alphabet letter, i.e., A..Z, a..z. $Recognize an ASCII lower case letter asciiLower(re.range "a" "z")prove $ \c -> (c :: SChar) `match` asciiLower .=> c `match` asciiLetterQ.E.D.prove $ \c -> c `match` asciiLower .=> toUpperL1 c `match` asciiUpperQ.E.D.prove $ \c -> c `match` asciiLetter .=> toLowerL1 c `match` asciiLowerQ.E.D. Recognize an upper case letter asciiUpper(re.range "A" "Z")prove $ \c -> (c :: SChar) `match` asciiUpper .=> c `match` asciiLetterQ.E.D.prove $ \c -> c `match` asciiUpper .=> toLowerL1 c `match` asciiLowerQ.E.D.prove $ \c -> c `match` asciiLetter .=> toUpperL1 c `match` asciiUpperQ.E.D. Recognize a digit. One of 0..9.digit(re.range "0" "9")prove $ \c -> c `match` digit .<=> let v = digitToInt c in 0 .<= v .&& v .< 10Q.E.D.7prove $ \c -> sNot ((c::SChar) `match` (digit - digit))Q.E.D. !Recognize an octal digit. One of 0..7.octDigit(re.range "0" "7")prove $ \c -> c `match` octDigit .<=> let v = digitToInt c in 0 .<= v .&& v .< 8Q.E.D.?prove $ \(c :: SChar) -> c `match` octDigit .=> c `match` digitQ.E.D. &Recognize a hexadecimal digit. One of 0..9, a..f, A..F.hexDigit(re.union (re.range "0" "9") (re.range "a" "f") (re.range "A" "F"))prove $ \c -> c `match` hexDigit .<=> let v = digitToInt c in 0 .<= v .&& v .< 16Q.E.D.?prove $ \(c :: SChar) -> c `match` digit .=> c `match` hexDigitQ.E.D. Recognize a decimal number.decimal(re.+ (re.range "0" "9"))prove $ \s -> (s::SString) `match` decimal .=> sNot (s `match` KStar asciiLetter)Q.E.D. :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")))prove $ \s -> s `match` octal .=> sAny (.== take 2 s) ["0o", "0O"]Q.E.D. ?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"))))prove $ \s -> s `match` hexadecimal .=> sAny (.== take 2 s) ["0x", "0X"]Q.E.D. Recognize a floating point number. The exponent part is optional if a fraction is present. The exponent may or may not have a sign.3prove $ \s -> s `match` floating .=> length s .>= 3Q.E.D. For the purposes of this regular expression, an identifier consists of a letter followed by zero or more letters, digits, underscores, and single quotes. The first letter must be lowercase. s `match` identifier .=> isAsciiLower (head s)Q.E.D.5prove $ \s -> s `match` identifier .=> length s .>= 1Q.E.D.!#Lift a unary operator over strings.!!Concrete evaluation for unary ops!$Quiet GHC about testing only imports Matching symbolic strings. Matching a character simply means the singleton string matches the regex.'  ' (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone7O^ 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. :The default configs corresponding to supported SMT solvers Return the known available solver configs, installed on your machine.!Turn a name into a symbolic type. If first argument is true, we'll also derive Eq and Ord instances. $Make an enumeration a symbolic type. Make an uninterpred sort.!*Make sure the given type is an enumeration!)Make sure the given type is an empty data 1(c) Brian Schroeder Levent ErkokBSD3erkokl@gmail.com experimentalNonec3!Ask solver for info.NB. For a version which generalizes over the underlying monad, see !Retrieve the value of an 'SMTOption.' The curious function argument is on purpose here, simply pass the constructor name. Example: the call !  will return either Nothing or Just (ProduceUnsatCores True) or Just (ProduceUnsatCores False).Result will be , if the solver does not support this option.NB. For a version which generalizes over the underlying monad, see !-Get the reason unknown. Only internally used.NB. For a version which generalizes over the underlying monad, see !0Get the observables recorded during a query run.NB. For a version which generalizes over the underlying monad, see !Get the uninterpreted constants/functions recorded during a run.NB. For a version which generalizes over the underlying monad, see !*Issue check-sat and get an SMT Result out.NB. For a version which generalizes over the underlying monad, see !Issue check-sat and get results of a lexicographic optimization.NB. For a version which generalizes over the underlying monad, see !Issue check-sat and get results of an independent (boxed) optimization.NB. For a version which generalizes over the underlying monad, see !,Construct a pareto-front optimization resultNB. For a version which generalizes over the underlying monad, see !Collect model values. It is implicitly assumed that we are in a check-sat context. See != for a variant that issues a check-sat first and returns an .NB. For a version which generalizes over the underlying monad, see !Check for satisfiability, under the given conditions. Similar to  except it allows making further assumptions as captured by the first argument of booleans. (Also see ! for a variant that returns the subset of the given assumptions that led to the  conclusion.)NB. For a version which generalizes over the underlying monad, see !Check for satisfiability, under the given conditions. Returns the unsatisfiable set of assumptions. Similar to  except it allows making further assumptions as captured by the first argument of booleans. If the result is , the user will also receive a subset of the given assumptions that led to the  conclusion. Note that while this set will be a subset of the inputs, it is not necessarily guaranteed to be minimal.You must have arranged for the production of unsat assumptions first via   $   for this call to not error out! Usage note: " is usually easier to use than !<, as it allows the use of named assertions, as obtained by . If "9 fills your needs, you should definitely prefer it over !.NB. For a version which generalizes over the underlying monad, see "The current assertion stack depth, i.e., #push - #pops after start. Always non-negative.NB. For a version which generalizes over the underlying monad, see "Run the query in a new assertion stack. That is, we push the context, run the query commands, and pop it back.NB. For a version which generalizes over the underlying monad, see "Push the context, entering a new one. Pushes multiple levels if n > 1.NB. For a version which generalizes over the underlying monad, see " 1. It's an error to pop levels that don't exist.NB. For a version which generalizes over the underlying monad, see "Search for a result via a sequence of case-splits, guided by the user. If one of the conditions lead to a satisfiable result, returns Just+ that result. If none of them do, returns Nothing. Note that we automatically generate a coverage case and search for it automatically as well. In that latter case, the string returned will be Coverage?. The first argument controls printing progress messages See ,Documentation.SBV.Examples.Queries.CaseSplit for an example use case.NB. For a version which generalizes over the underlying monad, see "Reset the solver, by forgetting all the assertions. However, bindings are kept as is, as opposed to a full reset of the solver. Use this variant to clean-up the solver state while leaving the bindings intact. Pops all assertion levels. Declarations and definitions resulting from the  command are unaffected. Note that SBV implicitly uses global-declarations, so bindings will remain intact.NB. For a version which generalizes over the underlying monad, see "Echo a string. Note that the echoing is done by the solver, not by SBV.NB. For a version which generalizes over the underlying monad, see "Exit the solver. This action will cause the solver to terminate. Needless to say, trying to communicate with the solver after issuing "exit" will simply fail.NB. For a version which generalizes over the underlying monad, see "Retrieve the unsat-core. Note you must have arranged for unsat cores to be produced first via   $   for this call to not error out!NB. There is no notion of a minimal unsat-core, in case unsatisfiability can be derived in multiple ways. Furthermore, Z3 does not guarantee that the generated unsat core does not have any redundant assertions either, as doing so can incur a performance penalty. (There might be assertions in the set that is not needed.) To ensure all the assertions in the core are relevant, use:   $  ":smt.core.minimize" ["true"] "Note that this only works with Z3.NB. For a version which generalizes over the underlying monad, see "Retrieve the proof. Note you must have arranged for proofs to be produced first via   $   for this call to not error out!A proof is simply a , as returned by the solver. In the future, SBV might provide a better datatype, depending on the use cases. Please get in touch if you use this function and can suggest a better API.NB. For a version which generalizes over the underlying monad, see "1Interpolant extraction for MathSAT. Compare with ", which performs similar function (but with a different use model) in Z3.!Retrieve an interpolant after an  result is obtained. Note you must have arranged for interpolants to be produced first via   $   for this call to not error out!-To get an interpolant for a pair of formulas A and B, use a ( call to attach interplation groups to A and B . Then call " ["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: # A .=> I and B .=> sNot I That is, it's evidence that A and B cannot be true together since A implies I but B implies not I; establishing that A and B5 cannot be satisfied at the same time. Furthermore, I0 will have only the symbols that are common to A and B.NB. Interpolant extraction isn't standardized well in SMTLib. Currently both MathSAT and Z3 support them, but with slightly differing APIs. So, we support two APIs with slightly differing types to accommodate both. See /Documentation.SBV.Examples.Queries.Interpolants& for example usages in these solvers.NB. For a version which generalizes over the underlying monad, see ",Interpolant extraction for z3. Compare with ", which performs similar function (but with a different use model) in MathSAT.3Unlike the MathSAT variant, you should simply call " on symbolic booleans to retrieve the interpolant. Do not call " or create named constraints. This makes it harder to identify formulas, but the current state of affairs in interpolant API requires this kludge.An interpolant for A and B is a formula I such that: " A ==> I and B ==> not I That is, it's evidence that A and B cannot be true together since A implies I but B implies not I; establishing that A and B5 cannot be satisfied at the same time. Furthermore, I0 will have only the symbols that are common to A and B.In Z3, interpolants generalize to sequences: If you pass more than two formulas, then you will get a sequence of interpolants. In general, for N formulas that are not satisfiable together, you will be returned N-1 interpolants. If formulas are A1 .. An, then interpolants will be  I1 .. I(N-1) , such that  A1 ==> I1, A2 /\ I1 ==> I2, A3 /\ I2 ==> I3, ..., and finally AN ===> not I(N-1).Currently, SBV only returns simple and sequence interpolants, and does not support tree-interpolants. If you need these, please get in touch. Furthermore, the result will be a list of mere strings representing the interpolating formulas, as opposed to a more structured type. Please get in touch if you use this function and can suggest a better API.NB. Interpolant extraction isn't standardized well in SMTLib. Currently both MathSAT and Z3 support them, but with slightly differing APIs. So, we support two APIs with slightly differing types to accommodate both. See /Documentation.SBV.Examples.Queries.Interpolants& for example usages in these solvers.NB. For a version which generalizes over the underlying monad, see "Get an abduct. The first argument is a conjecture. The return value will be an assertion such that in addition with the existing assertions you have, will imply this conjecture. The second argument is the grammar which guides the synthesis of this abduct, if given. Note that SBV doesn't do any checking on the grammar. See the relevant documentation on CVC5 for details.3NB. Before you use this function, make sure to call % setOption $ ProduceAbducts True to enable abduct generation."@?ABCDEIFGH/123485607 !,("#%$&')*+.-`a`a JKLMNAHFBCDEGI>?@/012345678 !"#$%&'()*+,-.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNonen4 Different kinds of "files" we can produce. Currently this is quite C specific. 5Representation of a collection of generated programs. Possible mappings for the  type when translated to C. Used in conjunction with the function  . Note that the particular characteristics of the mapped types depend on the platform and the compiler used for compiling the generated C program. See  )http://en.wikipedia.org/wiki/C_data_types for details. float double  long double The code-generation monad. Allows for precise layout of input values reference parameters (for returning composite values in languages such as C), and return values. Code-generation state %Abstraction of target language values Options for code-generation. If , then 8-bit unsigned values will be shown in hex as well, otherwise decimal. (Other types always shown in hex.) If 7, will overwrite the generated files without prompting. If , will ignore  calls If , will generate a makefile If  , will generate a driver program Values to use for the driver program generated, useful for generating non-random drivers. +Type to use for representing SReal (if any) 2Bit-size to use for representing SInteger (if any) If , perform run-time-checks for index-out-of-bounds or shifting-by-large values etc. 5Abstract over code generation for different languages Default options for code generation. The run-time checks are turned-off, and the driver values are completely random. )Initial configuration for code-generation .Reach into symbolic monad from code-generation Sets RTC (run-time-checks) for index-out-of-bounds, shift-with-large value etc. on/off. Default: . 4Sets number of bits to be used for representing the < 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. 0Sets the C type to be used for representing the > type in the generated C code. 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. .Should we generate a driver program? Default: . When a library is generated, it will have a driver if any of the constituent functions has a driver. (See .) (Should we generate a Makefile? Default: . Sets driver program run time values, useful for generating programs with fixed drivers for testing. Default: None, i.e., use random values. &Ignore assertions (those generated by  calls) in the generated C code Adds the given lines to the header file generated, useful for generating programs with uninterpreted functions.  If passed , then we will not ask the user if we're overwriting files as we generate the C code. Otherwise, we'll prompt.  If passed , then we will show 'SWord 8' type in hex. Otherwise we'll show it in decimal. All signed types are shown decimal, and all unsigned larger types are shown hexadecimal otherwise. Adds the given lines to the program file generated, useful for generating programs with uninterpreted functions. Adds the given words to the compiler options in the generated Makefile, useful for linking extra stuff in. .Creates an atomic input in the generated code. -Creates an array input in the generated code. /Creates an atomic output in the generated code. .Creates an array output in the generated code. 9Creates a returned (unnamed) value in the generated code. ?Creates a returned (unnamed) array value in the generated code. .Creates an atomic input in the generated code. -Creates an array input in the generated code. /Creates an atomic output in the generated code. .Creates an array output in the generated code. 9Creates a returned (unnamed) value in the generated code. ?Creates a returned (unnamed) array value in the generated code. Is this a driver program? Is this a make file? Generate code for a symbolic program, returning a Code-gen bundle, i.e., collection of makefiles, source code, headers, etc. 4Render a code-gen bundle to a directory or to stdout"An alternative to Pretty's render, which might have "leading" white-space in empty lines. This version eliminates such whitespace. (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 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 ! ".". Use  for printing to stdout.>The second argument is the name of the C function to generate.2The 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. Lower level version of  , producing a  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 ! ".". Use  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  , except in a list. Lower level version of  , producing a  "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."Renders as "const SWord8 s0", etc. the first parameter is the width of the typefield"Return the proper declaration and the result as a pair. No consts"3Renders as "s0", etc, or the corresponding constant"!Words as it would map to a C word"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."!The printf specifier for the type"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."Generate a makefile. The first argument is True if we have a driver."Generate the header""Generate an example driver program"Generate the C program"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."!Create a Makefile for the library"Create a driver for a library (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone  (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone Send an arbitrary string to the solver in a query. 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! 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. If the time-out is exceeded, then we will raise an error. 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! Send an arbitrary string to the solver in a query, and return a response. Note that this is inherently dangerous as it can put the solver in an arbitrary state and confuse SBV. Inverse transformation to  0. Note that this isn't a perfect inverse, since -0 maps to 0 and back to 0. Otherwise, it's faithful:prove $ \x -> let f = sComparableSWord32AsSFloat x in fpIsNaN f .|| fpIsNegativeZero f .|| sFloatAsComparableSWord32 f .== xQ.E.D.prove $ \x -> fpIsNegativeZero x .|| sComparableSWord32AsSFloat (sFloatAsComparableSWord32 x) `fpIsEqualObject` xQ.E.D. Inverse transformation to  0. Note that this isn't a perfect inverse, since -0 maps to 0 and back to 0. Otherwise, it's faithful:prove $ \x -> let d = sComparableSWord64AsSDouble x in fpIsNaN d .|| fpIsNegativeZero d .|| sDoubleAsComparableSWord64 d .== xQ.E.D.prove $ \x -> fpIsNegativeZero x .|| sComparableSWord64AsSDouble (sDoubleAsComparableSWord64 x) `fpIsEqualObject` xQ.E.D. Inverse transformation to  0. Note that this isn't a perfect inverse, since -0 maps to 0 and back to 0. Otherwise, it's faithful:prove $ \x -> let d :: SFPHalf = sComparableSWordAsSFloatingPoint x in fpIsNaN d .|| fpIsNegativeZero d .|| sFloatingPointAsComparableSWord d .== xQ.E.D.prove $ \x -> fpIsNegativeZero x .|| sComparableSWordAsSFloatingPoint (sFloatingPointAsComparableSWord x) `fpIsEqualObject` (x :: SFPHalf)Q.E.D.    _ VYXWTUjlm~nowr}tqy|spzx{uvkbdcfegVWXYbcdefgjklmnopqrstuvwxyz{|}~TU_    1(c) Brian Schroeder Levent ErkokBSD3erkokl@gmail.com experimentalNone '1>"7Conversion from a fixed-sized BV to a sized bit-vector. Convert a fixed-sized bit-vector to the corresponding sized bit-vector, for instance  to 'SWord 16'. See also  ."3Capture the correspondence in terms of a constraint  5, y + z .< x] NB. For a version which generalizes over the underlying monad, see 4Introduce a soft assertion, with an optional penaltyNB. For a version which generalizes over the underlying monad, see Minimize a named metricNB. For a version which generalizes over the underlying monad, see Maximize a named metricNB. For a version which generalizes over the underlying monad, see "1s'An queriable value: Mapping between concrete/symbolic values. If your type is traversable and simply embeds symbolic equivalents for one type, then you can simply define ". (Which is the most common case.)&^ Create a new symbolic value of type a,^ Extract the current value in a SAT context#^ Create a literal value. Morally,  and % are inverses of each other via the  monad transformer.$A type synonym for binary relations.:A helper class to convert sized bit-vectors to/from bytes.Convert to a sequence of bytesprove $ \a b c d -> toBytes ((fromBytes [a, b, c, d]) :: SWord 32) .== [a, b, c, d]Q.E.D. Convert from a sequence of bytes7prove $ \r -> fromBytes (toBytes r) .== (r :: SWord 64)Q.E.D.Show a value in detailed (cracked) form, if possible. This makes most sense with numbers, and especially floating-point types.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   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  .prove $ \x y -> (x `sBarrelRotateLeft` y) `sBarrelRotateRight` (y :: SWord32) .== (x :: SWord64)Q.E.D.An implementation of rotate-right, using a barrel shifter like design. See comments for  for details.prove $ \x y -> (x `sBarrelRotateRight` y) `sBarrelRotateLeft` (y :: SWord32) .== (x :: SWord64)Q.E.D.7Extract a portion of bits to form a smaller bit-vector.prove $ \x -> bvExtract (Proxy @7) (Proxy @3) (x :: SWord 12) .== bvDrop (Proxy @4) (bvTake (Proxy @9) x)Q.E.D.Join two bitvectors.prove $ \x y -> x .== bvExtract (Proxy @79) (Proxy @71) ((x :: SWord 9) # (y :: SWord 71))Q.E.D.Zero extend a bit-vector.prove $ \x -> bvExtract (Proxy @20) (Proxy @12) (zeroExtend (x :: SInt 12) :: SInt 21) .== 0Q.E.D.Sign extend a bit-vector.prove $ \x -> sNot (msb x) .=> bvExtract (Proxy @20) (Proxy @12) (signExtend (x :: SInt 12) :: SInt 21) .== 0Q.E.D.prove $ \x -> msb x .=> bvExtract (Proxy @20) (Proxy @12) (signExtend (x :: SInt 12) :: SInt 21) .== complement 0Q.E.D.'Drop bits from the top of a bit-vector.5prove $ \x -> bvDrop (Proxy @0) (x :: SWord 43) .== xQ.E.D.prove $ \x -> bvDrop (Proxy @20) (x :: SWord 21) .== ite (lsb x) 1 (0 :: SWord 1)Q.E.D.'Take bits from the top of a bit-vector.6prove $ \x -> bvTake (Proxy @13) (x :: SWord 13) .== xQ.E.D.prove $ \x -> bvTake (Proxy @1) (x :: SWord 13) .== ite (msb x) 1 0Q.E.D.prove $ \x -> bvTake (Proxy @4) x # bvDrop (Proxy @4) x .== (x :: SWord 23)Q.E.D.Check if a relation is a partial order. The string argument must uniquely identify this order.Check if a relation is a linear order. The string argument must uniquely identify this order.Check if a relation is a tree order. The string argument must uniquely identify this order.Check if a relation is a piece-wise linear order. The string argument must uniquely identify this order."$Make sure it's internally acceptableCreate the transitive closure of a given relation. The string argument must uniquely identify the newly created relation."9Check if the given relation satisfies the required axioms4Optimize lexicographically, with the default solver.3Optimize lexicographically, using the given solver.3Pareto front optimization, with the default solver.Pareto front optimization, with the given solver. The optional integer argument is the number of fronts to return. If , then we will return all pareto fronts. If the first component of the result is  then we reached the pareto-query limit specified by the user, so there might be more unqueried results remaining. If 3, it means that all the pareto fronts are returned.Independent optimization, with the default solver. In each result, string is the name of the objective optimized given by the user.Independent optimization, with the given solver. In each result, string is the name of the objective optimized given by the user. 1024 instance for  512 instance for  256 instance for  128 instance for  64 instance for  32 instance for  16 instance for  8 instance for Generic  instance for  valuesi : Start position, numbered from n-1 to 0j: End position, numbered from n-1 to 0, j <= i must holdInput bit vector of size nOutput is of size  i - j + 1First input, of size n, becomes the left sideSecond input, of size m, becomes the right sideConcatenation, of size n+mInput, of size nOutput, of size m. n < m must holdInput, of size nOutput, of size m. n < m must holdi: Number of bits to drop. i < n must hold.Input, of size nOutput, of size m.  m = n - i holds.i: Number of bits to take.  0 < i <= n must hold.Input, of size nOutput, of size i"""""""""""""""""""""      ^]    """""" """ "!! "!!"""""""""""""""""""""   9;:= sFalse)[]"ranges (\(_ :: SInteger) -> sTrue) [(-oo,oo)]ranges (\(x :: SInteger) -> sAnd [x .<= 120, x .>= -12, x ./= 3])[[-12,3),(3,120]]ranges (\(x :: SInteger) -> sAnd [x .<= 75, x .>= 5, x ./= 6, x ./= 67])[[5,6),(6,67),(67,75]]?ranges (\(x :: SInteger) -> sAnd [x .<= 75, x ./= 3, x ./= 67])[(-oo,3),(3,67),(67,75]]6ranges (\(x :: SReal) -> sAnd [x .>= 3.2, x .<= 12.7]) [[3.2,12.7]]4ranges (\(x :: SReal) -> sAnd [x .<= 12.7, x ./= 8])[(-oo,8.0),(8.0,12.7]]5ranges (\(x :: SReal) -> sAnd [x .>= 12.7, x ./= 15])[[12.7,15.0),(15.0,oo)]1ranges (\(x :: SInt8) -> sAnd [x .<= 7, x ./= 6])[[-128,6),(6,7]]ranges $ \x -> x .>= (0::SReal) [[0.0,oo)]ranges $ \x -> x .<= (0::SReal) [(-oo,0.0]]%ranges $ \(x :: SWord 4) -> 2*x .== 4[[2,3),(9,10]]5Compute ranges, using the given solver configuration.Show instance for (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone_Perform natural induction over the given function, which returns left and right hand-sides to be proven equal. Uses . That is, given f x = (lhs x, rhs x) , we inductively establish that lhs and rhs agree on 0, 1, ... n&, i.e., for all non-negative integers.import Data.SBV&import Data.SBV.Tools.NaturalInductionlet sumToN :: SInteger -> SInteger = smtFunction "sumToN" $ \x -> ite (x .<= 0) 0 (x + sumToN (x-1))let sumSquaresToN :: SInteger -> SInteger = smtFunction "sumSquaresToN" $ \x -> ite (x .<= 0) 0 (x*x + sumSquaresToN (x-1))1inductNat $ \n -> (sumToN n, (n*(n+1)) `sEDiv` 2)Q.E.D.inductNat $ \n -> (sumSquaresToN n, (n*(n+1)*(2*n+1)) `sEDiv` 6)Q.E.D.inductNat $ \n -> (sumSquaresToN n, ite (n .== 12) 0 ((n*(n+1)*(2*n+1)) `sEDiv` 6))Falsifiable. Counter-example:* P(0) = (0,0) :: (Integer, Integer)* P(k) = (506,506) :: (Integer, Integer)* P(k+1) = (650,0) :: (Integer, Integer) k = 11 :: Integer7Perform natural induction over, using the given solver.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone'/lGiven a predicate, return an induction principle for it. Typically, we only have one viable induction principle for a given type, but we allow for alternative ones.Proof for a property. This type is left abstract, i.e., the only way to create on is via a call to / etc., ensuring soundness. (Note that the trusted-code base here is still large: The underlying solver, SBV, and KnuckleDragger kernel itself. But this mechanism ensures we can't create proven things out of thin air, following the standard LCF methodology.)#User given name#Get the underlying boolean#$Was this an axiom given by the user?#Root of trust, described above.#Keeping track of where the sorry originates from. Used in displaying dependencies.#7Trusts nothing (aside from SBV, underlying solver etc.)#3Trusts itself, i.e., established by a call to sorry#Trusts a parent that itself trusts something else. Note the name here is the name of the proposition itself, not the parent that's trusted.A proposition is something SBV is capable of proving/disproving. We capture this with a set of constraints. This type might look scary, but for the most part you can ignore it and treat it as anything you can pass to   or   in SBV.Accept the given definition as a fact. Usually used to introduce definitial 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  should be limited to definitions, or basic axioms (like commutativity, associativity) of uninterpreted function symbols.#Internal axiom generator; so we can keep truck of KnuckleDrugger's trusted axioms, vs. user given axioms. Not exported.A manifestly false theorem. This is useful when we want to prove a theorem that the underlying solver cannot deal with, or if we want to postpone the proof for the time being. KnuckleDragger will keep track of the uses of 9 and will print them appropriately while printing proofs.#,Helper to generate lemma/theorem statements.Prove a given statement, using auxiliaries as helpers. Using the default solver.Prove a given statement, using auxiliaries as helpers. Using the given solver.Prove a given statement, using auxiliaries as helpers. Essentially the same as 0, except for the name, using the default solver.Prove a given statement, using auxiliaries as helpers. Essentially the same as , except for the name.#Show instance for #Induction over four argument predicates, with last argument a list.#Induction over three argument predicates, with last argument a list.#Induction over two argument predicates, with last argument a list.#Induction over lists#Induction over four argument predicates, with last argument SInteger.#Induction over three argument predicates, with last argument SInteger.#Induction over two argument predicates, with the last argument SInteger.#Induction over SInteger. We provide various induction principles here: The first one is over naturals, will only prove predicates that explicitly restrict the argument to >= 0. The second and third ones are induction over the entire range of integers, two different principles that might work better for different problems. # (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone '/1w5#A class for doing equational reasoning style chained proofs. Use  to prove a given theorem as a sequence of equalities, each step following from the previous.Prove a property via a series of equality steps, using the default solver. Let H. be a list of already established lemmas. Let P) be a property we wanted to prove, named name. Consider a call of the form  chainLemma name P [A, B, C, D] H . Note that H is a list of already proven facts, ensured by the type signature. We proceed as follows:Prove:  H -> A == BProve: H && A == B -> B == CProve: H && A == B && B == C -> C == DProve: $H && A == B && B == C && C == D -> P,If all of the above steps succeed, conclude P.&Note that if the type of steps (i.e., A .. D above) is , then we use implication as opposed to equality; which better captures line of reasoning.So, chain-lemma is essentially modus-ponens, applied in a sequence of stepwise equality reasoning in the case of non-boolean steps.(If there are no helpers given (i.e., if H, is empty), then this call is equivalent to . If H5 is a singleton, then we error-out. A single step in H indicates a user-error, since there's no sequence of steps to reason about.,Same as chainLemma, except tagged as TheoremProve a property via a series of equality steps, using the given solver.0Same as chainLemmaWith, except tagged as Theorem#1Internal, shouldn't be needed outside the libraryChaining lemmas that depend on five quantified variables. Overlapping version for  that uses implication.Chaining lemmas that depend on four quantified variables. Overlapping version for  that uses implication.Chaining lemmas that depend on three quantified variables. Overlapping version for  that uses implication.Chaining lemmas that depend on two quantified variables. Overlapping version for  that uses implication.Chaining lemmas that depend on a single quantified variable. Overlapping version for  that uses implication.9Chaining lemmas that depend on five quantified variables.9Chaining lemmas that depend on four quantified variables.:Chaining lemmas that depend on three quantified variables.8Chaining lemmas that depend on two quantified variables. SInteger bfac = bfix 10 "fac" fact where fact f n = ite (n .== 0) 1 (n * f (n-1)) This definition unrolls the recursion in factorial at most 10 times before uninterpreting the result. We can now prove:?prove $ \n -> n .>= 1 .&& n .<= 9 .=> bfac n .== n * bfac (n-1)Q.E.D.And we would get a bogus counter-example if the proof of our property needs a larger bound:-prove $ \n -> n .== 10 .=> bfac n .== 3628800Falsifiable. Counter-example: s0 = 10 :: Integer fac :: Integer -> Integer fac _ = 2The counter-example is telling us how it instantiated the function fac< when the recursion bottomed out: It simply made it return 2 for all arguments at that point, which provides the (unintended) counter-example.%By design, if a function defined via  is given a concrete argument, it will unroll the recursion as much as necessary to complete the call (which can of course diverge). The bound only applies if the given argument is symbolic. This fact can be used to observe concrete values to see where the bounded-model-checking approach fails:prove $ \n -> n .== 10 .=> observe "bfac_n" (bfac n) .== observe "bfac_10" (bfac 10)Falsifiable. Counter-example: bfac_10 = 3628800 :: Integer bfac_n = 7257600 :: Integer s0 = 10 :: Integer fac :: Integer -> Integer fac _ = 2Here, we see further evidence that the SMT solver must have decided to assign the value 2 in the final call just as it was reaching the base case, and thus got the final result incorrect. (Note that 7257600 = 2 * 3628800<.) A wrapper algorithm can then assert the actual value of bfac 10? here as an extra constraint and can search for "deeper bugs."(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneMaximize the value of an unsigned bit-vector value, using the default solver.Maximize the value of an unsigned bit-vector value, using the given solver.Minimize the value of an unsigned bit-vector value, using the default solver.Minimize the value of an unsigned bit-vector value, using the given solver.#min/max a given unsigned bit-vector. We walk down the bits in an incremental fashion. If we are maximizing, we try to make the bits set as we go down, otherwise we try to unset them. We keep adding the constraints so long as they are satisfiable, and at the end, get the optimal value produced.(Do we want unsat-cores if unsatisfiable?Value to maximize(Do we want unsat-cores if unsatisfiable?Value to minimize(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone#Are we covering or refuting?Refutation using bounded model checking, using the default solver. This version tries to refute the goal in a depth-first fashion. Note that this method can find a refutation, but will never find a "proof." If it finds a refutation, it will be the shortest, though not necessarily unique. Refutation using a given solver.Covers using bounded model checking, using the default solver. This version tries to cover the goal in a depth-first fashion. Note that this method can find a cover, but will never find determine that a goal is not coverable. If it finds a cover, it will be the shortest, though not necessarily unique.Cover using a given solver.#Bounded model checking, configurable with the solver. Not exported; use ,  and their "with" variants.Optional boundVerbose: prints iteration count.Setup code, if necessary. (Typically used for  calls. Pass  return () if not needed.)Initial conditionTransition relationGoal to cover, i.e., we find a set of transitions that satisfy this predicate.Either a result, or a satisfying path of given length and intermediate observations. Solver to useOptional boundVerbose: prints iteration count.Setup code, if necessary. (Typically used for  calls. Pass  return () if not needed.)Initial conditionTransition relationGoal to cover, i.e., we find a set of transitions that satisfy this predicate.Either a result, or a satisfying path of given length and intermediate observations.Optional boundVerbose: prints iteration count.Setup code, if necessary. (Typically used for  calls. Pass  return () if not needed.)Initial conditionTransition relationGoal to cover, i.e., we find a set of transitions that satisfy this predicate.Either a result, or a satisfying path of given length and intermediate observations. Solver to useOptional boundVerbose: prints iteration count.Setup code, if necessary. (Typically used for  calls. Pass  return () if not needed.)Initial conditionTransition relationGoal to cover, i.e., we find a set of transitions that satisfy this predicate.Either a result, or a satisfying path of given length and intermediate observations.(c) Brian HuffmanBSD3erkokl@gmail.com experimentalNoneDynamic variant of quick-check'Create SMT-Lib benchmark for a sat call)Create SMT-Lib benchmark for a proof call/Proves the predicate using the given SMT-solver7Find a satisfying assignment using the given SMT-solver'Check safety using the given SMT-solver:Find all satisfying assignments using the given SMT-solverProve a property with multiple solvers, running them in separate threads. The results will be returned in the order produced.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.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   is duplicated for each thread. This function will block until all child threads return.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   is duplicated for each thread. This function will return the first query computation that completes, killing the others.Find a satisfying assignment to a property with multiple solvers, running them in separate threads. The results will be returned in the order produced.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.Find a satisfying assignment to a property with multiple threads in query mode. The   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.Find a satisfying assignment to a property with multiple threads in query mode. The   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.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.)Extract a model dictionary. Extract a dictionary mapping the variables to their respective values as returned by the SMT solver. Also see .Create a named fresh existential variable in the current contextCreate an unnamed fresh existential variable in the current context  jlm~nowr}tqy|spzx{uvkjklmnopqrstuvwxyz{|}~   (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone9 Formalizes http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax Formalizes http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax Formalizes http://graphics.stanford.edu/~seander/bithacks.html#DetectOppositeSigns Formalizes http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching Formalizes http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2Collection of queries (c) Levent ErkokBSD3erkokl@gmail.com experimentalNonegModel the mid-point computation of the binary search, which is broken due to arithmetic overflow. Note how we use the overflow checking variants of the arithmetic operators. We have:!checkArithOverflow midPointBroken./Documentation/SBV/Examples/BitPrecise/BrokenSearch.hs:43:32:+!: SInt32 addition overflows: Violated. Model: low = 1073741832 :: Int32 high = 1107296257 :: Int32Indeed:*(1073741832 + 1107296257) `div` (2::Int32) -10569646041giving us quite a large negative mid-point value!The correct version of how to compute the mid-point. As expected, this version doesn't have any underflow or overflow issues: checkArithOverflow midPointFixedNo violations detected.1As expected, the value is computed correctly too:"checkCorrectMidValue midPointFixedQ.E.D.Show that the variant suggested by the blog post is good as well: 4mid = ((unsigned int)low + (unsigned int)high) >> 1;In this case the overflow is eliminated by doing the computation at a wider range:&checkArithOverflow midPointAlternativeNo violations detected.)And the value computed is indeed correct:(checkCorrectMidValue midPointAlternativeQ.E.D.=A helper predicate to check safety under the conditions that low is at least 0 and high is at least low.Another helper to show that the result is actually the correct value, if it was done over 64-bit integers, which is sufficiently large enough.!(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1=?(4Helper synonym for capturing relevant bits of MostekAn instruction is modeled as a  transformer. We model mostek programs in direct continuation passing style.Programs are essentially state transformers (on the machine state)0Given a machine state, compute a value out of itAbstraction of the machine: The CPU consists of memory, registers, and flags. Unlike traditional hardware, we assume the program is stored in some other memory area that we need not model. (No self modifying programs!)+ is equipped with an automatically derived ! instance because each field is .2Memory is simply an array from locations to values?We have three memory locations, sufficient to model our problem multiplicand multiplier'low byte of the result gets stored here Flag bank Register bank-Convenient synonym for symbolic machine bits.Mostek was an 8-bit machine.The carry flag () and the zero flag ()We model only two registers of Mostek that is used in the above algorithm, can add more.!Get the value of a given register!Set the value of a given registerGet the value of a flagSet the value of a flag Read memoryWrite to memory.Checking overflow. In Legato's multiplier the ADC instruction needs to see if the expression x + y + c overflowed, as checked by this function. Note that we verify the correctness of this check separately below in .Correctness theorem for our  implementation.We have:checkOverflowCorrectQ.E.D.LDX: Set register X to value vLDA: Set register A to value vCLC: Clear the carry flag9ROR, memory version: Rotate the value at memory location a to the right by 1 bit, using the carry flag as a transfer position. That is, the final bit of the memory location becomes the new carry and the carry moves over to the first bit. This very instruction is one of the reasons why Legato's multiplier is quite hard to understand and is typically presented as a verification challenge.ROR, register version: Same as , except through register r.BCC: branch to label l if the carry flag is sFalse%ADC: Increment the value of register A. by the value of memory contents at location a7, using the carry-bit as the carry-in for the addition.%DEX: Decrement the value of register X&BNE: Branch if the zero-flag is sFalseThe  combinator "stops" our program, providing the final continuation that does nothing.Multiplies the contents of F1 and F2), storing the low byte of the result in LO% and the high byte of it in register A. The implementation is a direct transliteration of Legato's algorithm given at the top, using our notation.Given values for F1 and F2,  runLegato" takes an arbitrary machine state m; and returns the high and low bytes of the multiplication.Create an instance of the Mostek machine, initialized by the memory and the relevant values of the registers and the flagsThe correctness theorem. For all possible memory configurations, the factors (x and y below), the location of the low-byte result and the initial-values of registers and the flags, this function will return True only if running Legato's algorithm does indeed compute the product of x and y correctly.The correctness theorem.Generate a C program that implements Legato's algorithm automatically.00"(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone3Element type of lists we'd like to sort. For simplicity, we'll just use ) here, but we can pick any symbolic type.5Merging two given sorted lists, preserving the order.Simple merge-sort implementation. We simply divide the input list in two halves so long as it has at least two elements, sort each half on its own, and then merge.1Check whether a given sequence is non-decreasing.Check whether two given sequences are permutations. We simply check that each sequence is a subset of the other, when considered as a set. The check is slightly complicated for the need to account for possibly duplicated elements.Asserting correctness of merge-sort for a list of the given size. Note that we can only check correctness for fixed-size lists. Also, the proof will get more and more complicated for the backend SMT solver as the list size increases. A value around 5 or 6 should be fairly easy to prove. For instance, we have: correctness 5Q.E.D.3Generate C code for merge-sorting an array of size n. Again, we're restricted to fixed size inputs. While the output is not how one would code merge sort in C by hand, it's a faithful rendering of all the operations merge-sort would do as described by its Haskell counterpart.#(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1?Parallel extraction: Given a source value and a mask, extract the bits in the source that are pointed to by the mask, and put it in the destination starting from the bottom.satWith z3{printBase = 16} $ \r -> r .== pext (0xAA :: SWord 8) 0xAASatisfiable. Model: s0 = 0x0f :: Word8prove $ \x -> pext @8 x 0 .== 0Q.E.D.,prove $ \x -> pext @8 x (complement 0) .== xQ.E.D.Parallel deposit: Given a source value and a mask, write into the destination that are allowed by the mask, grabbing the bits from the source starting from the bottom.satWith z3{printBase = 16} $ \r -> r .== pdep (0xFF :: SWord 8) 0xAASatisfiable. Model: s0 = 0xaa :: Word8prove $ \x -> pdep @8 x 0 .== 0Q.E.D.,prove $ \x -> pdep @8 x (complement 0) .== xQ.E.D.Prove that extraction and depositing with the same mask restore the source in all masked positions:extractThenDepositQ.E.D.Prove that depositing and extracting with the same mask will push preserve the bottom n-bits of the source, where n is the number of bits set in the mask.depositThenExtractQ.E.D.We can generate the code for these functions if they need to be used in SMTLib. Below is an example at 2-bits, which can be adjusted to produce any bit-size.putStrLn =<< sbv2smt pext_20; Automatically generated by SBV. Do not modify!); pext_2 :: SWord 2 -> SWord 2 -> SWord 2(define-fun pext_2 ((l1_s0 (_ BitVec 2)) (l1_s1 (_ BitVec 2))) (_ BitVec 2), (let ((l1_s3 #b0))- (let ((l1_s7 #b01))- (let ((l1_s8 #b00)). (let ((l1_s20 #b10)) (let ((l1_s2 ((_ extract 1 1) l1_s1)))? (let ((l1_s4 (distinct l1_s2 l1_s3))) (let ((l1_s5 ((_ extract 0 0) l1_s1)))? (let ((l1_s6 (distinct l1_s3 l1_s5))) (let ((l1_s9 (ite l1_s6 l1_s7 l1_s8)))9 (let ((l1_s10 (= l1_s7 l1_s9)))> (let ((l1_s11 (bvlshr l1_s0 l1_s7))) (let ((l1_s12 ((_ extract 0 0) l1_s11))) (let ((l1_s13 (distinct l1_s3 l1_s12)))9 (let ((l1_s14 (= l1_s8 l1_s9))) (let ((l1_s15 ((_ extract 0 0) l1_s0))) (let ((l1_s16 (distinct l1_s3 l1_s15))) (let ((l1_s17 (ite l1_s16 l1_s7 l1_s8))) (let ((l1_s18 (ite l1_s6 l1_s17 l1_s8)))= (let ((l1_s19 (bvor l1_s7 l1_s18)))? (let ((l1_s21 (bvand l1_s18 l1_s20))) (let ((l1_s22 (ite l1_s13 l1_s19 l1_s21))) (let ((l1_s23 (ite l1_s14 l1_s22 l1_s18)))> (let ((l1_s24 (bvor l1_s20 l1_s23)))> (let ((l1_s25 (bvand l1_s7 l1_s23))) (let ((l1_s26 (ite l1_s13 l1_s24 l1_s25))) (let ((l1_s27 (ite l1_s10 l1_s26 l1_s23))) (let ((l1_s28 (ite l1_s4 l1_s27 l1_s18)))< l1_s28))))))))))))))))))))))))))))$(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone A poor man's representation of powerlists and basic operations on them:  (http://dl.acm.org/citation.cfm?id=1973564 We merely represent power-lists by ordinary lists. The tie operator, concatenation.The zip operator, zips the power-lists of the same size, returns a powerlist of double the size.Inverse of zipping.Reference prefix sum (ps) is simply Haskell's scanl1 function.The Ladner-Fischer (lf$) implementation of prefix-sum. See  http://www.cs.utexas.edu/~plaxton/c/337/05f/slides/ParallelRecursion-4.pdf or pg. 16 of (http://dl.acm.org/citation.cfm?id=197356Correctness theorem, for a powerlist of given size, an associative operator, and its left-unit element.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:thm1Q.E.D.Proves Ladner-Fischer is equivalent to reference specification for the function max. 0; is the left-unit element, and we use a power-list of size 16 . We have:thm2Q.E.D.  %(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone,Simple function that returns add/sum of argsGenerate C code for addSub. Here's the output showing the generated C code: genAddSub%== BEGIN: "Makefile" ================# Makefile for addSub. Automatically generated by SBV. Do not edit!=# include any user-defined .mk file in the current directory. -include *.mkCC?=gcc0CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointerall: addSub_driveraddSub.o: addSub.c addSub.h ${CC} ${CCFLAGS} -c $< -o $@ addSub_driver.o: addSub_driver.c ${CC} ${CCFLAGS} -c $< -o $@'addSub_driver: addSub.o addSub_driver.o ${CC} ${CCFLAGS} $^ -o $@clean: rm -f *.overyclean: clean rm -f addSub_driver%== END: "Makefile" ==================%== BEGIN: "addSub.h" ================/* Header file for addSub. Automatically generated by SBV. Do not edit! */##ifndef __addSub__HEADER_INCLUDED__##define __addSub__HEADER_INCLUDED__#include #include #include #include #include #include #include /* 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: */8void addSub(const SWord8 x, const SWord8 y, SWord8 *sum, SWord8 *dif);(#endif /* __addSub__HEADER_INCLUDED__ */%== END: "addSub.h" ==================,== BEGIN: "addSub_driver.c" ================(/* Example driver program for addSub. */:/* Automatically generated by SBV. Edit as you see fit! */#include #include "addSub.h"int main(void){ SWord8 sum; SWord8 dif; addSub(132, 241, &sum, &dif);. printf("addSub(132, 241, &sum, &dif) ->\n");$ printf(" sum = %"PRIu8"\n", sum);$ printf(" dif = %"PRIu8"\n", dif); return 0;},== END: "addSub_driver.c" ==================%== BEGIN: "addSub.c" ================/* File: "addSub.c". Automatically generated by SBV. Do not edit! */#include "addSub.h"8void addSub(const SWord8 x, const SWord8 y, SWord8 *sum, SWord8 *dif){ const SWord8 s0 = x; const SWord8 s1 = y; const SWord8 s2 = s0 + s1; const SWord8 s3 = s0 - s1; *sum = s2; *dif = s3;}%== END: "addSub.c" ==================&(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneThe USB CRC polynomial:  x^5 + x^2 + 1. Although this polynomial needs just 6 bits to represent (5 if higher order bit is implicitly assumed to be set), we'll simply use a 16 bit number for its representation to keep things simple for code generation purposes.Given an 11 bit message, compute the CRC of it using the USB polynomial, which is 5 bits, and then append it to the msg to get a 16-bit word. Again, the incoming 11-bits is represented as a 16-bit word, with 5 highest bits essentially ignored for input purposes.(Alternate method for computing the CRC, mathematically. We shift the number to the left by 5, and then compute the remainder from the polynomial division by the USB polynomial. The result is then appended to the end of the message.Prove that the custom   function is equivalent to the mathematical definition of CRC's for 11 bit messages. We have:crcGoodQ.E.D.Generate a C function to compute the USB CRC, using the internal CRC function.Generate a C function to compute the USB CRC, using the mathematical definition of the CRCs. While this version generates functionally equivalent C code, it's less efficient; it has about 30% more code. So, the above version is preferable for code generation purposes.'*(c) Lee Pike Levent ErkokBSD3erkokl@gmail.com experimentalNoneEThis is a naive implementation of fibonacci, and will work fine (albeit slow) for concrete inputs:map fib0 [0..6][0 :: SWord64,1 :: SWord64,1 :: SWord64,2 :: SWord64,3 :: SWord64,5 :: SWord64,8 :: SWord64]However, it is not suitable for doing proofs or generating code, as it is not symbolically terminating when it is called with a symbolic value n. When we recursively call fib0 on n-1 (or n-2), the test against 0 will always explore both branches since the result will be symbolic, hence will not terminate. (An integrated theorem prover can establish termination after a certain number of unrollings, but this would be quite expensive to implement, and would be impractical.)The recursion-depth limited version of fibonacci. Limiting the maximum number to be 20, we can say:map (fib1 20) [0..6][0 :: SWord64,1 :: SWord64,1 :: SWord64,2 :: SWord64,3 :: SWord64,5 :: SWord64,8 :: SWord64]The function will work correctly, so long as the index we query is at most top*, and otherwise will return the value at top. Note that we also use accumulating parameters here for efficiency, although this is orthogonal to the termination concern.A note on modular arithmetic: The 64-bit word we use to represent the values will of course eventually overflow, beware! Fibonacci is a fast growing function..We can generate code for  using the  action. Note that the generated code will grow larger as we pick larger values of top, but only linearly, thanks to the accumulating parameter trick used by . The following is an excerpt from the code generated for the call  genFib1 10;, where the code will work correctly for indexes up to 10:  SWord64 fib1(const SWord64 x) { const SWord64 s0 = x; const SBool s2 = s0 == 0x0000000000000000ULL; const SBool s4 = s0 == 0x0000000000000001ULL; const SBool s6 = s0 == 0x0000000000000002ULL; const SBool s8 = s0 == 0x0000000000000003ULL; const SBool s10 = s0 == 0x0000000000000004ULL; const SBool s12 = s0 == 0x0000000000000005ULL; const SBool s14 = s0 == 0x0000000000000006ULL; const SBool s17 = s0 == 0x0000000000000007ULL; const SBool s19 = s0 == 0x0000000000000008ULL; const SBool s22 = s0 == 0x0000000000000009ULL; const SWord64 s25 = s22 ? 0x0000000000000022ULL : 0x0000000000000037ULL; const SWord64 s26 = s19 ? 0x0000000000000015ULL : s25; const SWord64 s27 = s17 ? 0x000000000000000dULL : s26; const SWord64 s28 = s14 ? 0x0000000000000008ULL : s27; const SWord64 s29 = s12 ? 0x0000000000000005ULL : s28; const SWord64 s30 = s10 ? 0x0000000000000003ULL : s29; const SWord64 s31 = s8 ? 0x0000000000000002ULL : s30; const SWord64 s32 = s6 ? 0x0000000000000001ULL : s31; const SWord64 s33 = s4 ? 0x0000000000000001ULL : s32; const SWord64 s34 = s2 ? 0x0000000000000000ULL : s33; return s34; },Compute the fibonacci numbers statically at code-generation0 time and put them in a table, accessed by the  call.  Once we have , we can generate the C code straightforwardly. Below is an excerpt from the code that SBV generates for the call  genFib2 64. Note that this code is a constant-time look-up table implementation of fibonacci, with no run-time overhead. The index can be made arbitrarily large, naturally. (Note that this function returns 0> if the index is larger than 64, as specified by the call to  with default 0.) SWord64 fibLookup(const SWord64 x) { const SWord64 s0 = x; static const SWord64 table0[] = { 0x0000000000000000ULL, 0x0000000000000001ULL, 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000003ULL, 0x0000000000000005ULL, 0x0000000000000008ULL, 0x000000000000000dULL, 0x0000000000000015ULL, 0x0000000000000022ULL, 0x0000000000000037ULL, 0x0000000000000059ULL, 0x0000000000000090ULL, 0x00000000000000e9ULL, 0x0000000000000179ULL, 0x0000000000000262ULL, 0x00000000000003dbULL, 0x000000000000063dULL, 0x0000000000000a18ULL, 0x0000000000001055ULL, 0x0000000000001a6dULL, 0x0000000000002ac2ULL, 0x000000000000452fULL, 0x0000000000006ff1ULL, 0x000000000000b520ULL, 0x0000000000012511ULL, 0x000000000001da31ULL, 0x000000000002ff42ULL, 0x000000000004d973ULL, 0x000000000007d8b5ULL, 0x00000000000cb228ULL, 0x0000000000148addULL, 0x0000000000213d05ULL, 0x000000000035c7e2ULL, 0x00000000005704e7ULL, 0x00000000008cccc9ULL, 0x0000000000e3d1b0ULL, 0x0000000001709e79ULL, 0x0000000002547029ULL, 0x0000000003c50ea2ULL, 0x0000000006197ecbULL, 0x0000000009de8d6dULL, 0x000000000ff80c38ULL, 0x0000000019d699a5ULL, 0x0000000029cea5ddULL, 0x0000000043a53f82ULL, 0x000000006d73e55fULL, 0x00000000b11924e1ULL, 0x000000011e8d0a40ULL, 0x00000001cfa62f21ULL, 0x00000002ee333961ULL, 0x00000004bdd96882ULL, 0x00000007ac0ca1e3ULL, 0x0000000c69e60a65ULL, 0x0000001415f2ac48ULL, 0x000000207fd8b6adULL, 0x0000003495cb62f5ULL, 0x0000005515a419a2ULL, 0x00000089ab6f7c97ULL, 0x000000dec1139639ULL, 0x000001686c8312d0ULL, 0x000002472d96a909ULL, 0x000003af9a19bbd9ULL, 0x000005f6c7b064e2ULL, 0x000009a661ca20bbULL }; const SWord64 s65 = s0 >= 65 ? 0x0000000000000000ULL : table0[s0]; return s65; }((c) Levent ErkokBSD3erkokl@gmail.com experimentalNone >The symbolic GCD algorithm, over two 8-bit numbers. We define sgcd a 0 to be a for all a, which implies  sgcd 0 0 = 0. Note that this is essentially Euclid's algorithm, except with a recursion depth counter. We need the depth counter since the algorithm is not symbolically terminating, as we don't have a means of determining that the second argument (b) will eventually reach 0 in a symbolic context. Hence we stop after 12 iterations. Why 12? We've empirically determined that this algorithm will recurse at most 12 times for arbitrary 8-bit numbers. Of course, this is a claim that we shall prove below.We have:prove sgcdIsCorrectQ.E.D.This call will generate the required C files. The following is the function body generated for ,. (We are not showing the generated header, Makefile, and the driver programs for brevity.) Note that the generated function is a constant time algorithm for GCD. It is not necessarily fastest, but it will take precisely the same amount of time for all values of x and y.  #include #include #include #include #include #include "sgcd.h" SWord8 sgcd(const SWord8 x, const SWord8 y) { const SWord8 s0 = x; const SWord8 s1 = y; const SBool s3 = s1 == 0; const SWord8 s4 = (s1 == 0) ? s0 : (s0 % s1); const SWord8 s5 = s3 ? s0 : s4; const SBool s6 = 0 == s5; const SWord8 s7 = (s5 == 0) ? s1 : (s1 % s5); const SWord8 s8 = s6 ? s1 : s7; const SBool s9 = 0 == s8; const SWord8 s10 = (s8 == 0) ? s5 : (s5 % s8); const SWord8 s11 = s9 ? s5 : s10; const SBool s12 = 0 == s11; const SWord8 s13 = (s11 == 0) ? s8 : (s8 % s11); const SWord8 s14 = s12 ? s8 : s13; const SBool s15 = 0 == s14; const SWord8 s16 = (s14 == 0) ? s11 : (s11 % s14); const SWord8 s17 = s15 ? s11 : s16; const SBool s18 = 0 == s17; const SWord8 s19 = (s17 == 0) ? s14 : (s14 % s17); const SWord8 s20 = s18 ? s14 : s19; const SBool s21 = 0 == s20; const SWord8 s22 = (s20 == 0) ? s17 : (s17 % s20); const SWord8 s23 = s21 ? s17 : s22; const SBool s24 = 0 == s23; const SWord8 s25 = (s23 == 0) ? s20 : (s20 % s23); const SWord8 s26 = s24 ? s20 : s25; const SBool s27 = 0 == s26; const SWord8 s28 = (s26 == 0) ? s23 : (s23 % s26); const SWord8 s29 = s27 ? s23 : s28; const SBool s30 = 0 == s29; const SWord8 s31 = (s29 == 0) ? s26 : (s26 % s29); const SWord8 s32 = s30 ? s26 : s31; const SBool s33 = 0 == s32; const SWord8 s34 = (s32 == 0) ? s29 : (s29 % s32); const SWord8 s35 = s33 ? s29 : s34; const SBool s36 = 0 == s35; const SWord8 s37 = s36 ? s32 : s35; const SWord8 s38 = s33 ? s29 : s37; const SWord8 s39 = s30 ? s26 : s38; const SWord8 s40 = s27 ? s23 : s39; const SWord8 s41 = s24 ? s20 : s40; const SWord8 s42 = s21 ? s17 : s41; const SWord8 s43 = s18 ? s14 : s42; const SWord8 s44 = s15 ? s11 : s43; const SWord8 s45 = s12 ? s8 : s44; const SWord8 s46 = s9 ? s5 : s45; const SWord8 s47 = s6 ? s1 : s46; const SWord8 s48 = s3 ? s0 : s47; return s48; })(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone"Given a 64-bit quantity, the simplest (and obvious) way to count the number of bits that are set in it is to simply walk through all the bits and add 1 to a running count. This is slow, as it requires 64 iterations, but is simple and easy to convince yourself that it is correct. For instance:popCountSlow 0x0123456789ABCDEF 32 :: SWord8Faster version. This is essentially the same algorithm, except we go 8 bits at a time instead of one by one, by using a precomputed table of population-count values for each byte. This algorithm loops= only 8 times, and hence is at least 8 times more efficient.Look-up table, containing population counts for all possible 8-bit value, from 0 to 255. Note that we do not "hard-code" the values, but merely use the slow version to compute them.States the correctness of faster population-count algorithm, with respect to the reference slow version. Turns out Z3's default solver is rather slow for this one, but there's a magic incantation to make it go fast. See  )http://github.com/Z3Prover/z3/issues/1150 for details.let cmd = "(check-sat-using (then (using-params ackermannize_bv :div0_ackermann_limit 1000000) simplify bit-blast sat))"0proveWith z3{satCmd = cmd} fastPopCountIsCorrectQ.E.D.Not only we can prove that faster version is correct, but we can also automatically 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 :genPopCountInC%== BEGIN: "Makefile" ================# Makefile for popCount. Automatically generated by SBV. Do not edit!=# include any user-defined .mk file in the current directory. -include *.mkCC?=gcc0CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointerall: popCount_driver!popCount.o: popCount.c popCount.h ${CC} ${CCFLAGS} -c $< -o $@$popCount_driver.o: popCount_driver.c ${CC} ${CCFLAGS} -c $< -o $@-popCount_driver: popCount.o popCount_driver.o ${CC} ${CCFLAGS} $^ -o $@clean: rm -f *.overyclean: clean rm -f popCount_driver%== END: "Makefile" =================='== BEGIN: "popCount.h" ================ BLANKLINE #ifndef popCountHEADER_INCLUDED__ #define popCountHEADER_INCLUDED__  BLANKLINE #include  stdio.h #include  stdlib.h #include  inttypes.h #include  stdint.h #include  stdbool.h #include  string.h #include  math.h BLANKLINEtypedef bool SBool; BLANKLINEtypedef float SFloat; BLANKLINEtypedef double SDouble; BLANKLINEtypedef uint8_t SWord8; typedef uint16_t SWord16; typedef uint32_t SWord32; typedef uint64_t SWord64; BLANKLINEtypedef int8_t SInt8; typedef int16_t SInt16; typedef int32_t SInt32; typedef int64_t SInt64; BLANKLINE#SWord8 popCount(const SWord64 x);  BLANKLINE #endif == END: "popCount.h" ================== == BEGIN: "popCount_driver.c" ================ BLANKLINE #include  stdio.h #include "popCount.h"  BLANKLINE int main(void) { const SWord8 __result = popCount(0x1b02e143e4f0e0e5ULL);  BLANKLINE/ printf("popCount(0x1b02e143e4f0e0e5ULL) = %PRIu8n", __result);  BLANKLINE return 0; } == END: "popCount_driver.c" ================== == BEGIN: "popCount.c" ================ BLANKLINE #include "popCount.h"  BLANKLINE SWord8 popCount(const SWord64 x) { const SWord64 s0 = x; 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, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 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;  BLANKLINE; return s41; } == END: "popCount.c" ==================*(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone&;A definition of shiftLeft that can deal with variable length shifts. (Note that the ! method from the " class requires an  shift amount.) Unfortunately, this'll generate rather clumsy C code due to the use of tables etc., so we uninterpret it for code generation purposes using the  function.Test function that uses shiftLeft defined above. When used as a normal Haskell function or in verification the definition is fully used, i.e., no uninterpretation happens. To wit, we have:tstShiftLeft 3 4 5224 :: SWord32,prove $ \x y -> tstShiftLeft x y 0 .== x + yQ.E.D.Generate C code for "tstShiftLeft". In this case, SBV will *use* the user given definition verbatim, instead of generating code for it. (Also see the functions  ,  , and  .)+(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1PThe key schedule. AES executes in rounds, and it treats first and last round keys slightly differently than the middle ones. We reflect that choice by being explicit about it in our type. The length of the middle list of keys depends on the key-size, which in turn determines the number of rounds.The key, which can be 128, 192, or 256 bits. Represented as a sequence of 32-bit words.AES state. The state consists of four 32-bit words, each of which is in turn treated as four GF28's, i.e., 4 bytes. The T-Box implementation keeps the four-bytes together for efficient representation.An element of the Galois Field 2^8, which are essentially polynomials with maximum degree 7. They are conveniently represented as values between 0 and 255.Multiplication in GF(2^8). This is simple polynomial multiplication, followed by the irreducible polynomial x^8+x^4+x^3+x^1+1. We simply use the  / function exported by SBV to do the operation.Exponentiation by a constant in GF(2^8). The implementation uses the usual square-and-multiply trick to speed up the computation.Computing inverses in GF(2^8). By the mathematical properties of GF(2^8) and the particular irreducible polynomial used x^8+x^5+x^3+x^1+1, it turns out that raising to the 254 power gives us the multiplicative inverse. Of course, we can prove this using SBV::prove $ \x -> x ./= 0 .=> x `gf28Mult` gf28Inverse x .== 1Q.E.D.Note that we exclude 0? in our theorem, as it does not have a multiplicative inverse.4Rotating a state row by a fixed amount to the right.Definition of round-constants, as specified in Section 5.2 of the AES standard.The  InvMixColumns transformation, as described in Section 5.3.3 of the standard. Note that this transformation is only used explicitly during key-expansion in the T-Box implementation of AES.Key expansion. Starting with the given key, returns an infinite sequence of words, as described by the AES standard, Section 5.2, Figure 11.The values of the AES S-box table. Note that we describe the S-box programmatically using the mathematical construction given in Section 5.1.1 of the standard. However, the code-generation will turn this into a mere look-up table, as it is just a constant table, all computation being done at "compile-time".The sbox transformation. We simply select from the sbox table. Note that we are obliged to give a default value (here 0) to be used if the index is out-of-bounds as required by SBV's  function. However, that will never happen since the table has all 256 elements in it.The values of the inverse S-box table. Again, the construction is programmatic.!The inverse s-box transformation.Prove that the  and  are inverses. We have:prove sboxInverseCorrectQ.E.D.Adding the round-key to the current state. We simply exploit the fact that addition is just xor in implementing this transformation..T-box table generation function for encryption&First look-up table used in encryption'Second look-up table used in encryption&Third look-up table used in encryption'Fourth look-up table used in encryption.T-box table generating function for decryption&First look-up table used in decryption'Second look-up table used in decryption&Third look-up table used in decryption'Fourth look-up table used in decryptionGeneric round function. Given the function to perform one round, a key-schedule, and a starting state, it performs the AES rounds.One encryption round. The first argument indicates whether this is the final round or not, in which case the construction is slightly different.One decryption round. Similar to the encryption round, the first argument indicates whether this is the final round or not.Key schedule. Given a 128, 192, or 256 bit key, expand it to get key-schedules for encryption and decryption. The key is given as a sequence of 32-bit words. (4 elements for 128-bits, 6 for 192, and 8 for 256.) Compare this function to  which can calculate the key-expansion for decryption on the fly, as opposed to calculating the forward key-expansion first.Block encryption. The first argument is the plain-text, which must have precisely 4 elements, for a total of 128-bits of input. The second argument is the key-schedule to be used, obtained by a call to . The output will always have 4 32-bit words, which is the cipher-text.3Block decryption. The arguments are the same as in , except the first argument is the cipher-text and the output is the corresponding plain-text.Inverse key expansion. Starting from the final round key, unwinds key generation operation to construct keys for the previous rounds. Used in on-the-fly decryption.AES inverse key schedule. Starting from the last-round key, construct the sequence of keys that can be used for doing on-the-fly decryption. Compare this function to  which returns both encryption and decryption schedules: In this case, we don't calculate the encryption sequence, hence we can fuse this function with the decryption operation.Block decryption, starting from the unwound key. That is, start from the final key. Also; we don't use the T-box implementation. Just pure AES inverse cipher."Common plain text for test vectorsKey for 128-bit encryption testKey for 192-bit encryption testKey for 256-bit encryption test+Expected cipher-text for 128-bit encryption+Expected cipher-text for 192-bit encryption+Expected cipher-text for 256-bit encryptionCalculate the 128-bit final-round key from on-the-fly decryption key scheduleCalculate the 192-bit final-round key from on-the-fly decryption key scheduleCalculate the 192-bit final-round key from on-the-fly decryption key schedule. Compare this to : Typically we just need the final 6-blocks, but it is advantageous to have the entire last 8-blocks even for 192-bit keys. That is, e store the final 256-bits of key-expansion for speed purposes for both 192 and 256 bit versions. (But only the final 128 bits for the 128-bit version.)Calculate the 256-bit final-round key from on-the-fly decryption key scheduleExtract the final key for on-the-fly decryption. This will extract exactly the number of blocks we need.Extract the extended key for on-the-fly decryption. This will extract 4-blocks for 128-bit decryption, but 256 bit for both 192 and 256-bit variants?128-bit encryption test, from Appendix C.1 of the AES standard:map hex8 t128Enc-["69c4e0d8","6a7b0430","d8cdb780","70b4c55a"]?128-bit decryption test, from Appendix C.1 of the AES standard:map hex8 t128Dec-["00112233","44556677","8899aabb","ccddeeff"]?192-bit encryption test, from Appendix C.2 of the AES standard:map hex8 t192Enc-["dda97ca4","864cdfe0","6eaf70a0","ec0d7191"]?192-bit decryption test, from Appendix C.2 of the AES standard:map hex8 t192Dec-["00112233","44556677","8899aabb","ccddeeff"]:256-bit encryption, from Appendix C.3 of the AES standard:map hex8 t256Enc-["8ea2b7ca","516745bf","eafc4990","4b496089"]:256-bit decryption, from Appendix C.3 of the AES standard:map hex8 t256Dec-["00112233","44556677","8899aabb","ccddeeff"]1Various tests for round-trip properties. We have:runAESTests False GOOD: Key generation AES128GOOD: Key generation AES192GOOD: Key generation AES256GOOD: Encryption AES128GOOD: Decryption AES128GOOD: Decryption-OTF AES128GOOD: Encryption AES192GOOD: Decryption AES192GOOD: Decryption-OTF AES192GOOD: Encryption AES256GOOD: Decryption AES256GOOD: Decryption-OTF AES256;Correctness theorem for 128-bit AES. Ideally, we would run:  prove aes128IsCorrect to get a proof automatically. Unfortunately, while SBV will successfully generate the proof obligation for this theorem and ship it to the SMT solver, it would be naive to expect the SMT-solver to finish that proof in any reasonable time with the currently available SMT solving technologies. Instead, we can issue:  quickCheck aes128IsCorrect and get some degree of confidence in our code. Similar predicates can be easily constructed for 192, and 256 bit cases as well.128-bit encryption, that takes 128-bit values, instead of chunks. We have:hex8 $ aes128Enc 0x000102030405060708090a0b0c0d0e0f 0x00112233445566778899aabbccddeeff""69c4e0d86a7b0430d8cdb78070b4c55a"You can also render this function as a stand-alone function using: . sbv2smt (smtFunction "aes128Enc" aes128Enc) +Code generation for 128-bit AES encryption.The following sample from the generated code-lines show how T-Boxes are rendered as C arrays:  static const SWord32 table1[] = { 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, ... } 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:  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 GNU C-compiler does a fine job of optimizing this straightline code to generate a fairly efficient C implementation.Components of the AES implementation that the library is generated from. For each case, we provide the driver values from the AES test-vectors.8Generate code for AES functionality; given the key size.Generate a C library, containing functions for performing 128-bit encdeckey-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.)For doctest purposes onlyChunk in groups of 4. (This function must be in some standard library, where?)plain-text words key-words+True if round-trip gives us plain-text back,(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1X A nibble is 4-bits. Ideally, we would like to represent a nibble by SWord 4; and indeed SBV can do that for verification purposes just fine. Unfortunately, the SBV's C compiler doesn't support 4-bit bit-vectors, as there's nothing meaningful in the C-land that we can map it to. Thus, we represent a nibble with 8-bits. The top 4 bits will always be 0.$Cypher text is another 64-bit block.Key is again a 64-bit block.Plantext is simply a block.Section 2: Prince is essentially a 64-bit cipher, with 128-bit key, coming in two parts..Expanding a key, from Section 3.4 of the spec.0expandKey(x) = x has a unique solution. We have:prop_ExpandKeyQ.E.D.Section 2: Encryption DecryptionBasic prince algorithmCore prince. It's essentially folding of 12 rounds stitched together:Forward round.Backend round.M transformation. Inverse of M.SR.Inverse of SR:)Prove sr and srInv are inverses: We have: prove prop_srQ.E.D.M' transformation&The matrix as described in Section 3.3Multiplication.$Non-linear transformation of a blockSBox transformation.Inverse SBox transformation.2Prove that sbox and sBoxInv are inverses: We have:prove prop_SBoxQ.E.D.Round constantsRound-constants property: rc_i " rc_{11-i} is constant. We have:prop_RoundKeysTrue Convert a 64 bit word to nibbles%Convert from nibbles to a 64 bit word%From Appendix A of the spec. We have: testVectorsTrueNicely show a concrete block.+Generating C code for the encryption block.  -(c) Austin SeippBSD3erkokl@gmail.com experimentalNoneb :Represents the current state of the RC4 stream: it is the S array along with the i and j index values used by the PRGA.The key is a stream of  values.RC4 State contains 256 8-bit values. We use the symbolically accessible full-binary type   to represent the state, since RC4 needs access to the array via a symbolic index and it's important to minimize access time.Construct the fully balanced initial tree, where the leaves are simply the numbers 0 through 255.$Swaps two elements in the RC4 array.Implements the PRGA used in RC4. We return the new state and the next key value generated.Constructs the state to be used by the PRGA using the given key.The key-schedule. Note that this function returns an infinite list.0Generate a key-schedule from a given key-string.RC4 encryption. We generate key-words and xor it with the input. The following test-vectors are from Wikipedia  http://en.wikipedia.org/wiki/RC4:*concatMap hex2 $ encrypt "Key" "Plaintext""bbf316e8d940af0ad3"'concatMap hex2 $ encrypt "Wiki" "pedia" "1021bf0420"2concatMap hex2 $ encrypt "Secret" "Attack at dawn""45a01f645fc35b383552544b9bf5"RC4 decryption. Essentially the same as decryption. For the above test vectors we have:decrypt "Key" [0xbb, 0xf3, 0x16, 0xe8, 0xd9, 0x40, 0xaf, 0x0a, 0xd3] "Plaintext"-decrypt "Wiki" [0x10, 0x21, 0xbf, 0x04, 0x20]"pedia"decrypt "Secret" [0x45, 0xa0, 0x1f, 0x64, 0x5f, 0xc3, 0x5b, 0x38, 0x35, 0x52, 0x54, 0x4b, 0x9b, 0xf5]"Attack at dawn"Prove that round-trip encryption/decryption leaves the plain-text unchanged. The theorem is stated parametrically over key and plain-text sizes. The expression performs the proof for a 40-bit key (5 bytes) and 40-bit plaintext (again 5 bytes).Note that this theorem is trivial to prove, since it is essentially establishing xor'in the same value twice leaves a word unchanged (i.e., x " y " y = x). However, the proof takes quite a while to complete, as it gives rise to a fairly large symbolic trace.For doctest purposes only  .(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone'1l%5 is a synonym for lists, but makes the intent clear.Parameterized SHA representation, that captures all the differences between variants of the algorithm. w is the word-size type.Section 6.2.2, 6.4.2: How many iterations are there in the inner loop(Section 5.3.2-6 : Initial hash value)Section 4.2.2-3 : Magic SHA constants9Section 4.1.2-3 : Coefficients of the sigma1 function9Section 4.1.2-3 : Coefficients of the sigma0 function7Section 4.1.2-3 : Coefficients of the Sum1 function7Section 4.1.2-3 : Coefficients of the Sum0 function-Section 1 : Block size for messages/Section 1 : Word size we operate withThe choose function.The majority function.The sum-0 function. We parameterize over the rotation amounts as different variants of SHA use different rotation amounts.)The sum-1 function. Again, parameterized.#The sigma0 function. Parameterized.#The sigma1 function. Parameterized.Parameterization for SHA224.9Parameterization for SHA256. Inherits mostly from SHA224.Parameterization for SHA384.9Parameterization for SHA512. Inherits mostly from SHA384. 2^64 (or 2^128), and you'd run out of memory first!Hash one block of message, starting from a previous hash. This function corresponds to body of the for-loop in the spec. This function always produces a list of length 8, corresponding to the final 8 values of the H.Compute the hash of a given string using the specified parameterized hash algorithm.SHA224 digest.SHA256 digest.SHA384 digest.SHA512 digest.SHA512_224 digest.SHA512_256 digest.Collection of known answer tests for SHA. Since these tests take too long during regular regression runs, we pass as an argument how many to run. Increase the below number to 24 to run all tests. We have:knownAnswerTests 1TrueGenerate code for one block of SHA256 in action, starting from an arbitrary hash value.Generate code for one block of SHA512 in action, starting from an arbitrary hash value.Helper for chunking a list by given lengths and combining each chunk with a function'Nicely lay out a hash value as a string''/(c) Levent ErkokBSD3erkokl@gmail.com experimentalNonenE)Encode the delta-sat problem as given in  http://dreal.github.io/ We have:flyspeck Unsatisfiable0(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1{(For a homogeneous problem, the solution is any linear combination of the resulting vectors. For a non-homogeneous problem, the solution is any linear combination of the vectors in the second component plus one of the vectors in the first component.ldn: Solve a (L)inear (D)iophantine equation, returning minimal solutions over (N)aturals. The input is given as a rows of equations, with rhs values separated into a tuple. The first argument must be a proxy of a natural, must be total number of columns in the system. (i.e., #of variables + 1). The second parameter limits the search to bound: In case there are too many solutions, you might want to limit your search space.Find the basis solution. By definition, the basis has all non-trivial (i.e., non-0) solutions that cannot be written as the sum of two other solutions. We use the mathematically equivalent statement that a solution is in the basis if it's least according to the natural partial order using the ordinary less-than relation.Solve the equation: 2x + y - z = 2We have:test(k, 2+k', 2k+k')(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. It's harder to see that they cover all possibilities, but a moments thought reveals that is indeed the case.A puzzle: Five sailors and a monkey escape from a naufrage and reach an island with coconuts. Before dawn, they gather a few of them and decide to sleep first and share the next day. At night, however, one of them awakes, counts the nuts, makes five parts, gives the remaining nut to the monkey, saves his share away, and sleeps. All other sailors do the same, one by one. When they all wake up in the morning, they again make 5 shares, and give the last remaining nut to the monkey. How many nuts were there at the beginning?7We can model this as a series of diophantine equations:  x_0 = 5 x_1 + 1 4 x_1 = 5 x_2 + 1 4 x_2 = 5 x_3 + 1 4 x_3 = 5 x_4 + 1 4 x_4 = 5 x_5 + 1 4 x_5 = 5 x_6 + 1 We need to solve for x_0, over the naturals. If you run this program, z3 takes its time (quite long!) but, it eventually computes: [15621,3124,2499,1999,1599,1279,1023] as the answer.That is:  * There was a total of 15621 coconuts * 1st sailor: 15621 = 3124*5+1, leaving 15621-3124-1 = 12496 * 2nd sailor: 12496 = 2499*5+1, leaving 12496-2499-1 = 9996 * 3rd sailor: 9996 = 1999*5+1, leaving 9996-1999-1 = 7996 * 4th sailor: 7996 = 1599*5+1, leaving 7996-1599-1 = 6396 * 5th sailor: 6396 = 1279*5+1, leaving 6396-1279-1 = 5116 * In the morning, they had: 5116 = 1023*5+1. Note that this is the minimum solution, that is, we are guaranteed that there's no solution with less number of coconuts. In fact, any member of [15625*k-4 | k <- [1..]] is a solution, i.e., so are 31246, 46871, 62496, 78121, etc.Note that we iteratively deepen our search by requesting increasing number of solutions to avoid the all-sat pitfall.1(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 178?~.*Use an uninterpreted type for the elementsSymbolic version of the type . xs ++ [] == xsWe have: appendNull.Lemma: appendNull Q.E.D.[Proven] appendNull  (x : xs) ++ ys == x : (xs ++ ys)We have:consApp.Lemma: consApp Q.E.D.[Proven] consApp $(xs ++ ys) ++ zs == xs ++ (ys ++ zs)We have: appendAssoc.Lemma: appendAssoc Q.E.D.[Proven] appendAssoc reverse (reverse xs) == xsWe have:reverseReverse.Lemma: revApp Q.E.D..Lemma: reverseReverse Q.E.D.[Proven] reverseReverse2(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone178? (Use an uninterpreted type for the domainsTrue is provable.We have:trueIsProvable.Lemma: true Q.E.D. [Proven] truesFalse isn't provable.We have:=falseIsn'tProvable `catch` (\(_ :: SomeException) -> pure ()) Lemma: sFalse*** Failed to prove sFalse. FalsifiableBasic quantification example: For every integer, there's a larger integer.We have: >>> largerIntegerExists Lemma: largerIntegerExists Q.E.D. [Proven] largerIntegerExistsSymbolic version of the type .1Pushing a universal through conjunction. We have:forallConjunction.Lemma: forallConjunction Q.E.D.[Proven] forallConjunction4Pushing an existential through disjunction. We have:existsDisjunction.Lemma: existsDisjunction Q.E.D.[Proven] existsDisjunction:We cannot push a universal through a disjunction. We have:?forallDisjunctionNot `catch` (\(_ :: SomeException) -> pure ()) Lemma: forallConjunctionNot)*** Failed to prove forallConjunctionNot.Falsifiable. Counter-example: p :: T -> Bool p T_2 = True p T_0 = True p _ = False q :: T -> Bool q T_2 = False q T_0 = False 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.);We cannot push an existential through conjunction. We have:?existsConjunctionNot `catch` (\(_ :: SomeException) -> pure ()) Lemma: existsConjunctionNot)*** Failed to prove existsConjunctionNot.Falsifiable. Counter-example: p :: T -> Bool p T_1 = False p _ = True q :: T -> Bool q T_1 = True q _ = FalseIn this case, we again have a predicate That disagree at every point, providing a counter-example.  3(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1 The default settings for z3 have trouble running this proof out-of-the-box. We have to pass auto_config=false to z3! Prove that  2n^2 + n + 1 is not divisible by 3.We have:notDiv3Chain: case_n_mod_3_eq_0. Lemma: case_n_mod_3_eq_0.1 Q.E.D.. Lemma: case_n_mod_3_eq_0.2 Q.E.D..Lemma: case_n_mod_3_eq_0 Q.E.D.Chain: case_n_mod_3_eq_1. Lemma: case_n_mod_3_eq_1.1 Q.E.D.. Lemma: case_n_mod_3_eq_1.2 Q.E.D..Lemma: case_n_mod_3_eq_1 Q.E.D.Chain: case_n_mod_3_eq_2. Lemma: case_n_mod_3_eq_2.1 Q.E.D.. Lemma: case_n_mod_3_eq_2.2 Q.E.D..Lemma: case_n_mod_3_eq_2 Q.E.D..Lemma: notDiv3 Q.E.D.[Proven] notDiv34(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1FProve that sum of constants c from 0 to n is n*c.We have: sumConstProof.Lemma: sumConst_correct Q.E.D.[Proven] sumConst_correctProve that sum of numbers from 0 to n is  n*(n-1)/2.We have:sumProof.Lemma: sum_correct Q.E.D.[Proven] sum_correct)Prove that sum of square of numbers from 0 to n is n*(n+1)*(2n+1)/6.We have:sumSquareProof.Lemma: sumSquare_correct Q.E.D.[Proven] sumSquare_correct Prove that  11^n - 4^n is always divisible by 7. Note that power operator is hard for SMT solvers to deal with due to non-linearity. For this example, we use cvc5 to discharge the final goal, where z3 can't converge on it.We have:elevenMinusFour.Lemma: pow0 Q.E.D..Lemma: powN Q.E.D..Lemma: elevenMinusFour Q.E.D.[Proven] elevenMinusFour5(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 178?yAn uninterpreted sort, corresponding to the type of Kleene algebra strings.Symbolic version of the type .Star operator over kleene algebras. We're leaving this uninterpreted.The set of strings matched by one regular expression is a subset of the second, if adding it to the second doesn't change the second set.)A sequence of Kleene algebra proofs. See .http://www.cs.cornell.edu/~kozen/Papers/ka.pdfWe have: kleeneProofs.Axiom: par_assoc Axiom..Axiom: par_comm Axiom..Axiom: par_idem Axiom..Axiom: par_zero Axiom..Axiom: seq_assoc Axiom..Axiom: seq_zero Axiom..Axiom: seq_one Axiom..Axiom: rdistrib Axiom..Axiom: ldistrib Axiom..Axiom: unfold Axiom..Axiom: least_fix Axiom..Lemma: par_lzero Q.E.D..Lemma: par_monotone Q.E.D..Lemma: seq_monotone Q.E.D.Chain: star_star_1. Lemma: star_star_1.1 Q.E.D.. Lemma: star_star_1.2 Q.E.D.. Lemma: star_star_1.3 Q.E.D.. Lemma: star_star_1.4 Q.E.D..Lemma: star_star_1 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.The  instance for Kleene makes it easy to write regular expressions in the more familiar form.6(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 178?g*Use an uninterpreted type for the elementsSymbolic version of the type .Prove that the length of a list is one more than the length of its tail.We have:listLengthProof.Lemma: length_correct Q.E.D.[Proven] length_correctIt is instructive to see what kind of counter-example we get if a lemma fails to prove. Below, we do a variant of the , but with a bad implementation over integers, and see the counter-example. Our implementation returns an incorrect answer if the given list is longer than 5 elements and have 42 in it. We have:3badProof `catch` (\(_ :: SomeException) -> pure ()) Lemma: bad*** Failed to prove bad.Falsifiable. Counter-example:( xs = [8,25,26,27,28,42] :: [Integer]& imp = 42 :: Integer& spec = 6 :: Integer *length (xs ++ ys) == length xs + length ysWe have: lenAppend.Lemma: lenAppend Q.E.D.[Proven] lenAppend  length (xs ++ ys) == 2 * length xsWe have: lenAppend2.Lemma: lenAppend2 Q.E.D.[Proven] lenAppend27(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone178?*Use an uninterpreted type for the elementsSymbolic version of the type .  length xs == length (reverse xs)We have:revLen.Lemma: revLen Q.E.D.[Proven] revLenAn example where we attempt to prove a non-theorem. Notice the counter-example generated for: /length xs = ite (length xs .== 3) 5 (length xs)We have:4badRevLen `catch` (\(_ :: SomeException) -> pure ())Lemma: badRevLen*** Failed to prove badRevLen.Falsifiable. Counter-example:# xs = [Elt_1,Elt_2,Elt_1] :: [Elt]8(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1Prove that square-root of 2+ is irrational. That is, we can never find a and b such that sqrt 2 == a / b and a and b are co-prime.In order not to deal with reals and square-roots, we prove the integer-only alternative: If  a^2 = 2b^2, then a and b cannot be co-prime. We proceed by establishing the following helpers first: An odd number squared is odd: odd x -> odd x^2An even number that is a perfect square must be the square of an even number: even x^2 -> even x.>If a number is even, then its square must be a multiple of 4: even x .=> x*x % 4 == 0."Using these helpers, we can argue: Start with the premise  a^2 = 2b^2.Thus, a^2 must be even. (Since it equals 2b^2 by a.)Thus, a must be even. (Using 2 and b.)Thus, a^2 must be divisible by 42. (Using 3 and c. That is, 2b^2 == 4*K for someK.)Thus, b^2# must be even. (Using d, b^2 = 2K.) Thus, b must be even. (Using 2 and e.) Since a and b9 are both even, they cannot be co-prime. (Using c and f.)Note that our proof is mostly about the first 3 facts above, then z3 and KnuckleDragger fills in the rest.We have:sqrt2IsIrrational Chain: oddSquaredIsOdd. Lemma: oddSquaredIsOdd.1 Q.E.D.. Lemma: oddSquaredIsOdd.2 Q.E.D..Lemma: oddSquaredIsOdd Q.E.D..Lemma: squareEvenImpliesEven Q.E.D.Chain: evenSquaredIsMult4. Lemma: evenSquaredIsMult4.1 Q.E.D..Lemma: evenSquaredIsMult4 Q.E.D..Lemma: sqrt2IsIrrational Q.E.D.[Proven] sqrt2IsIrrational9(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone178?3Create an uninterpreted type to do the proofs over.Symbolic version of the type . Prove that:  (x op x) op y == y op x  means that op is commutative.We have:tao.Lemma: tao Q.E.D. [Proven] tao:(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone #78? ,Each agent can be in one of the three states Regular work!Intention to enter critical stateIn the critical stateSymbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .A bounded mutex property holds for two sequences of state transitions, if they are not in their critical section at the same time up to that given bound.1A sequence is valid upto a bound if it starts at ', and follows the mutex rules. That is:From  it can switch to  or stay From  it can switch to  if it's its turnFrom  it can either stay in  or go back to  The variable me identifies the agent id.The mutex algorithm, coded implicitly as an assignment to turns. Turns start at 1, and at each stage is either 1 or 2; giving preference to that process. The only condition is that if either process is in its critical section, then the turn value stays the same. Note that this is sufficient to satisfy safety (i.e., mutual exclusion), though it does not guarantee liveness.1Check that we have the mutex property so long as  and  holds; i.e., so long as both the agents and the arbiter act according to the rules. The check is bounded up-to-the given concrete bound; so this is an example of a bounded-model-checking style proof. We have: checkMutex 20 All is good!Our algorithm is correct, but it is not fair. It does not guarantee that a process that wants to enter its critical-section will always do so eventually. Demonstrate this by trying to show a bounded trace of length 10, such that the second process is ready but never transitions to critical. We have: ghci> notFair 10 Fairness is violated at bound: 10 P1: [Idle,Idle,Ready,Critical,Idle,Idle,Ready,Critical,Idle,Idle] P2: [Idle,Ready,Ready,Ready,Ready,Ready,Ready,Ready,Ready,Ready] Ts: [1,2,1,1,1,1,1,1,1,1]As expected, P2 gets ready but never goes critical since the arbiter keeps picking P1 unfairly. (You might get a different trace depending on what z3 happens to produce!)$Exercise for the reader: Change the  function so that it alternates the turns from the previous value if neither process is in critical. Show that this makes the  function below no longer exhibits the issue. Is this sufficient? Concurrent programming is tricky!  ;(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone:A deck is simply a list of integers. Note that a regular deck will have distinct cards, we do not impose this in our proof. That is, the proof works regardless whether we put duplicates into the deck, which generalizes the theorem.$Count-out-and-transfer (COAT): Take k cards from top, reverse it, and put it at the bottom of a deck. COAT 4 times.4Key property of COATing. If you take a deck of size n, and COAT it 4 times, then the deck remains in the same order. The COAT factor, k6, must be greater than half the size of the deck size.6Note that the proof time increases significantly with n.. Here's a proof for deck size of 6, for all k >= 3. coatCheck 6Q.E.D.It's interesting to note that one can also express this theorem by making n symbolic as well. However, doing so definitely requires an inductive proof, and the SMT-solver doesn't handle this case out-of-the-box, running forever.<(c) Joel BurgetBSD3erkokl@gmail.com experimentalNone`3Compute a prefix of the fibonacci numbers. We have: mkFibs 10[1,1,2,3,5,8,13,21,34,55]Generate fibonacci numbers as a sequence. Note that we constrain only the first 200 entries.=(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone"+A simple predicate, based on two variables x and y , true when  0 <= x <= 1 and  x - abs y is 0.=Generate all satisfying assignments for our problem. We have: allModels Solution #1: x = 1 :: Integer y = -1 :: Integer Solution #2: x = 1 :: Integer y = 1 :: Integer Solution #3: x = 0 :: Integer y = 0 :: IntegerFound 3 different solutions.Note that solutions 2 and 3 share the value x = 1&, since there are multiple values of y% that make this particular choice of x satisfy our constraint.Generate all satisfying assignments, but we first tell SBV that y should not be considered as a model problem, i.e., it's auxiliary. We have:modelsWithYAux Solution #1: x = 1 :: Integer Solution #2: x = 0 :: IntegerFound 2 different solutions.Note that we now have only two solutions, one for each unique value of x that satisfy our constraint.>(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone#©Add one to an argumentReverse run the add1 function. Note that the generated SMTLib will have the function add1 itself defined. You can verify this by running the below in verbose mode. add1ExampleSatisfiable. Model: x = 4 :: IntegerSum 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.$Prove that sumToN works as expected.We have: sumToNExampleSatisfiable. Model: s0 = 5 :: Integer s1 = 15 :: IntegerCoding list-length recursively. Again, we map directly to an SMTLib function.:Calculate the length of a list, using recursive functions.We have: lenExampleSatisfiable. Model: s0 = [1,2,3] :: [Integer] s1 = 3 :: IntegerA simple mutual-recursion example, from the z3 documentation. We have:pingPongSatisfiable. Model: s0 = 1 :: IntegerUsual way to define even-odd mutually recursively. Unfortunately, while this goes through, the backend solver does not terminate on this example. See  for an alternative technique to handle such definitions, which seems to be more solver friendly.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.+Extract the isEven function for easier use.*Extract the isOdd function for easier use.7We can prove 20 is even and definitely not odd, thusly:evenOdd2Satisfiable. Model: s0 = 20 :: Integer s1 = True :: Bool s2 = False :: Bool3Ackermann function, demonstrating nested recursion.8We can prove constant-folding instances of the equality ack 1 y == y + 2:ack1ySatisfiable. Model: s0 = 5 :: Integer s1 = 7 :: Integer>Expecting the prover to handle the general case for arbitrary y is beyond the current scope of what SMT solvers do out-of-the-box for the time being.?(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone78? 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.Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .Have the SMT solver enumerate the elements of the domain. We have:elts Solution #1: s0 = C :: E Solution #2: s0 = B :: E Solution #3: s0 = A :: EFound 3 different solutions.9Shows that if we require 4 distinct elements of the type , we shall fail; as the domain only has three elements. We have:four UnsatisfiableEnumerations are automatically ordered, so we can ask for the maximum element. Note the use of quantification. We have:maxESatisfiable. Model: maxE = C :: E/Similarly, we get the minimum element. We have:minESatisfiable. Model: minE = A :: E  @(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 178?/An uninterpreted sort for demo purposes, named /An uninterpreted sort for demo purposes, named Symbolic version of the type .,An enumerated type for demo purposes, named Symbolic version of the type .Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .Helper to turn quantified formula to a regular boolean. We can think of this as quantifier elimination, hence the name .Consider the formula \forall x\,\exists y\, x \ge y;, over bit-vectors of size 8. We can ask SBV to satisfy it: sat skolemEx1 SatisfiableBut this isn't really illimunating. We can first skolemize, and then ask to satisfy:sat $ skolemize skolemEx1Satisfiable. Model: y :: Word8 -> Word8 y x = xwhich is much better We are told that we can have the witness as the value given for each choice of x.Consider the formula ;\forall a\,\exists b\,\forall c\,\exists d\, a + b >= c + d;, over bit-vectors of size 8. We can ask SBV to satisfy it: sat skolemEx2 SatisfiableAgain, we're left in the dark as to why this is satisfiable. Let's skolemize first, and then call   on it:sat $ skolemize skolemEx2Satisfiable. Model: b :: Word8 -> Word8 b _ = 0 d :: Word8 -> Word8 -> Word8 d a c = a + 255 * cLet'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, 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 a >= 256c + a a >= a showing the formula is satisfiable for whatever values you pick for a and c . Note that 256 is simply 0 when interpreted modulo 2^8 . Clever!A common proof technique to show validity is to show that the negation is unsatisfiable. Note that if you want to skolemize during this process, you should first negate and then skolemize!4This example demonstrates the possible pitfall. The  function encodes \exists x\, \forall y\, y \ge x9 for 8-bit bitvectors; which is a valid statement since x = 08 acts as the witness. We can directly prove this in SBV:prove skolemEx3Q.E.D.0Or, we can ask if the negation is unsatisfiable:sat (qNot skolemEx3) Unsatisfiable5If we want, we can skolemize after the negation step: sat (skolemize (qNot skolemEx3)) Unsatisfiable.and get the same result. However, it would be unsound$ to skolemize first and then negate: sat (qNot (skolemize skolemEx3))Satisfiable. Model: x = 1 :: Word8And that would be the incorrect conclusion that our formula is invalid with a counter-example! You can see the same by doing:prove (skolemize skolemEx3)Falsifiable. Counter-example: x = 1 :: Word8So, if you want to check validity and want to also perform skolemization; you should negate your formula first and then skolemize, not the other way around!If you skolemize different formulas that share the same name for their existentials, then SBV will get confused and will think those represent the same skolem function. This is unfortunate, but it follows the requirement that uninterpreted function names should be unique. In this particular case, however, since SBV creates these functions, it is harder to control the internal names. In such cases, use the function  to provide a name to prefix the skolem functions. As demonstrated by  . We get: skolemEx4Satisfiable. Model: c1_y :: Integer -> Integer c1_y x = x c2_y :: Integer -> Integer c2_y x = x + 1Note how the internal skolem functions are named according to the tag given. If you use regular  this program will essentially do the wrong thing by assuming the skolem functions for both predicates are the same, and will return unsat. Beware! All skolem functions should be named differently in your program for your deductions to be sound./Demonstrates creating a partial order. We have: poExampleQ.E.D.Create a transitive relation of a simple relation and show that transitive connections are respected. We have: tcExample1Q.E.D.Another transitive-closure example, this time we show the transitive closure is the smallest relation, i.e., doesn't have extra connections. We have: tcExample2Q.E.D.Demonstrates computing the transitive closure of existing relations. We have: tcExample3Q.E.D.A(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1Prove that floating point addition is not associative. For illustration purposes, we will require one of the inputs to be a NaN . We have:prove $ assocPlus (0/0)Falsifiable. Counter-example: s0 = 0.0 :: Float s1 = 0.0 :: FloatIndeed:let i = 0/0 :: Floati + (0.0 + 0.0)NaN((i + 0.0) + 0.0)NaNBut keep in mind that NaN< does not equal itself in the floating point world! We have:$let nan = 0/0 :: Float in nan == nanFalse:Prove that addition is not associative, even if we ignore NaN/Infinity+ values. To do this, we use the predicate  -, which is true of a floating point number ( or ) if it is neither NaN nor Infinity. (That is, it's a representable point in the real-number line.)We have:assocPlusRegularFalsifiable. Counter-example: x = 4.4272205e21 :: Float y = 2.9514347e20 :: Float z = 4.4676022e15 :: FloatIndeed, we have:let x = 4.4272205e21 :: Floatlet y = 2.9514347e20 :: Floatlet z = 4.4676022e15 :: Float x + (y + z) 4.722369e21 (x + y) + z 4.722368e21/Note the significant difference in the results!Demonstrate that a+b = a does not necessarily mean b is 0 in the floating point world, even when we disallow the obvious solution when a and b are  Infinity. We have:nonZeroAdditionFalsifiable. Counter-example: a = 2.9670994e34 :: Float b = -7.208359e-5 :: FloatIndeed, we have:let a = 2.9670994e34 :: Floatlet b = -7.208359e-5 :: Float a + b == aTrueb == 0FalseThis example illustrates that  a * (1/a) does not necessarily equal 1). Again, we protect against division by 0 and NaN/Infinity.We have: multInverseFalsifiable. Counter-example: a = -1.4991268e38 :: FloatIndeed, we have:let a = -1.4991268e38 :: Float a * (1/a) 0.99999994One interesting aspect of floating-point is that the chosen rounding-mode can effect the results of a computation if the exact result cannot be precisely represented. SBV exports the functions  ,  ,  ,  ,   and  2 which allows users to specify the IEEE supported b for the operation. This example illustrates how SBV can be used to find rounding-modes where, for instance, addition can produce different results. We have: roundingAddSatisfiable. Model:* rm = RoundTowardPositive :: RoundingMode# x = -4.0039067 :: Float# y = 131076.0 :: 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  type does. We have:sat $ \x -> x .== (fpAdd sRoundTowardPositive (-4.0039067) 131076.0 :: SFloat)Satisfiable. Model: s0 = 131072.0 :: Float (-4.0039067) + 131076.0 :: Float 131071.99We can see why these two results are indeed different: The 'RoundTowardPositive (which rounds towards positive infinity) produces a larger result.!(-4.0039067) + 131076.0 :: Double131071.9960933>we see that the "more precise" result is larger than what the  value is, justifying the larger value with 'RoundTowardPositive. A more detailed study is beyond our current scope, so we'll merely note that floating point representation and semantics is indeed a thorny subject, and point to  http://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf as an excellent guide.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 and maximum floating point values with exponent width 5 and significand width 4, which is actually 3 bits for the significand explicitly stored, includes the hidden bit. We have: fp54Bounds.Objective "toMetricSpace(max)": Optimal model: x = 61440 :: FloatingPoint 5 4.Objective "toMetricSpace(min)": Optimal model:& x = 0.000007629 :: FloatingPoint 5 4An important note is in order. When printing floats in decimal, one can get correct yet surprising results. There's a large body of publications in how to render floats in decimal, or in bases that are not powers of two in general. So, when looking at such values in decimal, keep in mind that what you see might be a representative value: That is, it preserves the value when translated back to the format. For instance, the more precise answer for the min value would be 2^-17, which is 0.00000762939453125. But we see it truncated here. In fact, any number between 2^-16 and 2^-17 would be correct as they all map to the same underlying representation in this format. Moral of the story is that when reading floating-point numbers in decimal notation one should be very careful about the printed representation and the numeric value; while they will match in value (if there are no bugs!), they can print quite differently! (Also keep in mind the rounding modes that impact how the conversion is done.)One final note: When printing the models, we skip optimization variables that are not named x. See the call to . When we optimize floating-point values, the underlying engine actually optimizes with bit-vector values, producing intermediate results. We skip those here to simplify the presentation.B(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneGiven an array, and bounds on it, initialize it within the bounds to the element given. Otherwise, leave it untouched.Prove a simple property: If we read from the initialized region, we get the initial value. We have: memsetExampleQ.E.D.Get an example of reading a value out of range. The value returned should be out-of-range for lo/hi outOfInitSatisfiable. Model: Read = 1 :: Integer) mem = ([], 1) :: Array Integer Integer lo = 0 :: Integer hi = 0 :: Integer zero = 0 :: Integer idx = 1 :: IntegerC(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneA simple function to generate a new integer value, that is not in the given set of values. We also require the value to be non-negativeWe 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 by less than 5. Here, we use the < function. We could have also extracted the dictionary via < and did fancier programming as well, as necessary. We have:genVals[45,40,35,30,25,20,15,10,5,0]D(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneModel a nested array that is indexed by integers, and we store another integer to integer array in each index. We have: nestedArray(0,10)E2(c) Curran McConnell Levent ErkokBSD3erkokl@gmail.com experimentalNonet Symbolic version of .Similarly, we can create another newtype, this time wrapping over . As an example, consider measuring the human height in centimetres? The tallest person in history, Robert Wadlow, was 272 cm. We don't need negative values, so , is the smallest type that suits our needs.Symbolic version of .A  is a newtype wrapper around .5The tallest human ever was 272 cm. We can simply use # to lift it to the symbolic space.Given a distance between a floor and a ceiling, we can see whether the human can stand in that room. Comparison is expressed using  .Now, suppose we want to see whether we could design a room with a ceiling high enough that any human could stand in it. We have: sat problemSatisfiable. Model:! floorToCeiling = 3 :: Integer humanheight = 272 :: Word16The  instance simply uses stock definitions. This is always possible for newtypes that simply wrap over an existing symbolic type.To use  symbolically, we associate it with the underlying symbolic type's kind.Similarly here, for the  instance.Symbolic instance simply follows the underlying type, just like .  F(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone1A simple variant of division, where we explicitly require the caller to make sure the divisor is not 0.#Check whether an arbitrary call to 5 is safe. Clearly, we do not expect this to be safe:test1[./Documentation/SBV/Examples/Misc/NoDiv0.hs:38:14:checkedDiv: Divisor should not be 0: Violated. Model: s0 = 0 :: Int32 s1 = 0 :: Int32]Repeat the test, except this time we explicitly protect against the bad case. We have:test2[./Documentation/SBV/Examples/Misc/NoDiv0.hs:46:41:checkedDiv: Divisor should not be 0: No violations detected]G(c) Levent ErkokBSD3erkokl@gmail.com experimentalNonewHelper synonym for representing GF(2^8); which are merely 8-bit unsigned words. Largest term in such a polynomial has degree 7.Multiplication in Rijndael's field; usual polynomial multiplication followed by reduction by the irreducible polynomial. The irreducible used by Rijndael's field is the polynomial x^8 + x^4 + x^3 + x + 1 , which we write by giving it's  exponents in SBV. See:  http://en.wikipedia.org/wiki/Finite_field_arithmetic#Rijndael.27s_finite_field. Note that the irreducible itself is not in GF28! It has a degree of 8.NB. You can use the   function to print polynomials nicely, as a mathematician would write. States that the unit polynomial 1, is the unit element)States that multiplication is commutativeStates that multiplication is associative, note that associativity proofs are notoriously hard for SAT/SMT solversStates that the usual multiplication rule holds over GF(2^n) polynomials Checks:  if (a, b) = x   y then x = y   a + b being careful about y = 0. When divisor is 0, then quotient is defined to be 0 and the remainder is the numerator. (Note that addition is simply " in GF(2^8).)QueriesH(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone Symbolic version of #d1 x y = if y < x - 2 then 7 else 2Symbolic version of #d2 x y = if y > 3 then 10 else 50Symbolic version of (d3 x y = if y < -x + 3 then 100 else 200Symbolic version of !d4 x y = d1 x y + d2 x y + d3 x y5Compute all possible program paths. Note the call to  , which causes   to find models that generate differing values for the given expression. We have:paths Solution #1: x = -2 :: Integer y = 4 :: Integer r = 112 :: Integer Solution #2: x = 0 :: Integer y = 3 :: Integer r = 252 :: Integer Solution #3: x = -1 :: Integer y = 4 :: Integer r = 212 :: Integer Solution #4: x = 3 :: Integer y = 0 :: Integer r = 257 :: Integer Solution #5: x = 2 :: Integer y = -1 :: Integer r = 157 :: Integer Solution #6: x = 7 :: Integer y = 4 :: Integer r = 217 :: Integer Solution #7: x = 0 :: Integer y = 0 :: Integer r = 152 :: IntegerFound 7 different solutions.I(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone Abbreviation for set of integers. For convenience only in monomorphising the properties.J(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone" Create two strings, requiring one to be a particular value, constraining the other to be different than another constant string. But also add soft constraints to indicate our preferences for each of these variables. We get:exampleSatisfiable. Model:( x = "x-must-really-be-hello" :: String( y = "default-y-value" :: StringNote how the value of x is constrained properly and thus the default value doesn't kick in, but y takes the default value since it is acceptable by all the other hard constraints.K-(c) Joel Burget Levent ErkokBSD3erkokl@gmail.com experimentalNone"UA dictionary is a list of lookup values. Note that we store the type [(a, b)]8 as a symbolic value here, mixing sequences and tuples.Create a dictionary of length 5, such that each element has an string key and each value is the length of the key. We impose a few more constraints to make the output interesting. For instance, you might get:  ghci> example [("nt_",3),("dHAk",4),("kzkk0",5),("mZxs9s",6),("c32'dPM",7)] Depending on your version of z3, a different answer might be provided. Here, we check that it satisfies our length conditions: import Data.List (genericLength)example >>= \ex -> return (length ex == 5 && all (\(l, i) -> genericLength l == i) ex)TrueL(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 78?A simple enumerationSymbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .Identify weekend daysUsing optimization, find the latest day that is not a weekend. We have: almostWeekendOptimal model:# last-day = Fri :: Day# almostWeekend = Fri :: Day% DayAsWord8(last-day) = 4 :: Word8Using optimization, find the first day after the weekend. We have:weekendJustOverOptimal model:$ first-day = Mon :: Day$ weekendJustOver = Mon :: Day& DayAsWord8(first-day) = 0 :: Word89Using optimization, find the first weekend day: We have: firstWeekendOptimal model:( first-weekend = Sat :: Day( firstWeekend = Sat :: Day* DayAsWord8(first-weekend) = 5 :: Word80Make day an optimizable value, by mapping it to  in the most obvious way. We can map it to any value the underlying solver can optimize, but ( is the simplest and it'll fit the bill.M(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneOptimization goals where min/max values might require assignments to values that are infinite (integer case), or infinite/epsilon (real case). This simple example demonstrates how SBV can be used to extract such values.We have:optimize Independent problem 1Objective "one-x": Optimal in an extension field: one-x = oo :: Integer min_y = 7.0 :: Real min_z = 5.0 :: Real1Objective "min_y": Optimal in an extension field: one-x = oo :: Integer min_y = 7.0 :: Real min_z = 5.0 :: Real1Objective "min_z": Optimal in an extension field: one-x = oo :: Integer min_y = 7.0 :: Real min_z = 5.0 :: RealN(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone Taken from 6http://people.brunel.ac.uk/~mastjjb/jeb/or/morelp.htmlmaximize 5x1 + 6x2 subject to  x1 + x2 <= 10 x1 - x2 >= 35x1 + 4x2 <= 35x1 >= 0x2 >= 0optimize Lexicographic problemOptimal model: x1 = 47 % 9 :: Real x2 = 20 % 9 :: Real goal = 355 % 9 :: RealO(c) Levent ErkokBSD3erkokl@gmail.com experimentalNonet Taken from 6http://people.brunel.ac.uk/~mastjjb/jeb/or/morelp.htmlA company makes two products (X and Y) using two machines (A and B).Each unit of X that is produced requires 50 minutes processing time on machine A and 30 minutes processing time on machine B.Each unit of Y that is produced requires 24 minutes processing time on machine A and 33 minutes processing time on machine B.At the start of the current week there are 30 units of X and 90 units of Y in stock. Available processing time on machine A is forecast to be 40 hours and on machine B is forecast to be 35 hours.The demand for X in the current week is forecast to be 75 units and for Y is forecast to be 95 units.Company policy is to maximise the combined sum of the units of X and the units of Y in stock at the end of the week. 0 \Rightarrow inv (x, y, z, i)Second verification condition: If the loop body executes, invariant must still hold at the end:=inv (x, y, z, i) \land i < y \Rightarrow inv (x, y, z+1, i+1)Third verification condition: Once the loop exits, invariant and the negation of the loop condition must establish the final assertion:6inv (x, y, z, i) \land i \geq y \Rightarrow z == x + ySynthesize the invariant. We use an uninterpreted function for the SMT solver to synthesize. We get: synthesizeSatisfiable. Model:; invariant :: (Integer, Integer, Integer, Integer) -> Bool invariant (x, y, z, i) = x + (-z) + i > (-1) && x + (-z) + i < 1 && x + y + (-z) > (-1)This is a bit hard to read, but you can convince yourself it is equivalent to x + i .== z .&& x + y .>= z:let f (x, y, z, i) = x + (-z) + i .> (-1) .&& x + (-z) + i .< 1 .&& x + y + (-z) .> (-1)0let g (x, y, z, i) = x + i .== z .&& x + y .>= zf === (g :: Inv)Q.E.D.Verify that the synthesized function does indeed work. To do so, we simply prove that the invariant found satisfies all the vcs:verifyQ.E.D.R(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone ':;<0}*System state, containing the two integers.We parameterize over the initial state for different variations.Example 1: We start from x=0, y=10, and search up to depth 10 . We have:ex1BMC Cover: Iteration: 0BMC Cover: Iteration: 1BMC Cover: Iteration: 2BMC Cover: Iteration: 30BMC Cover: Satisfying state found at iteration 3$Right (3,[(0,10),(0,6),(0,2),(2,2)])As expected, there's a solution in this case. Furthermore, since the BMC engine found a solution at depth 34, we also know that there is no solution at depths 0, 1, or 2; i.e., this is "a" shortest solution. (That is, it may not be unique, but there isn't a shorter sequence to get us to our goal.)Example 2: We start from x=0, y=11, and search up to depth 10 . We have:ex2 BMC Cover: Iteration: 0BMC Cover: Iteration: 1BMC Cover: Iteration: 2BMC Cover: Iteration: 3BMC Cover: Iteration: 4BMC Cover: Iteration: 5BMC Cover: Iteration: 6BMC Cover: Iteration: 7BMC Cover: Iteration: 8BMC Cover: Iteration: 9Left "BMC Cover limit of 10 reached. Cover can't be established."As expected, there's no solution in this case. While SBV (and BMC) cannot establish that there is no solution at a larger depth, you can see that this will never be the case: In each step we do not change the parity of either variable. That is, x will remain even, and y will remain odd. So, there will never be a solution at any depth. This isn't the only way to see this result of course, but the point remains that BMC is just not capable of establishing inductive facts.!'Queriable instance for our stateSymbolic equality for S.Show the state as a pairS(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone ':;<3!System state. We simply have two components, parameterized over the type so we can put in both concrete and symbolic values.;Encoding partial correctness of the sum algorithm. We have: fibCorrectQ.E.D.NB. In my experiments, I found that this proof is quite fragile due to the use of quantifiers: If you make a mistake in your algorithm or the coding, z3 pretty much spins forever without finding a counter-example. However, with the correct coding, the proof is almost instantaneous!!'Queriable instance for our stateT(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone ':;<: System state. We simply have two components, parameterized over the type so we can put in both concrete and symbolic values.We parameterize over the transition relation and the strengthenings to investigate various combinations.2The first program, coded as a transition relation:3The second program, coded as a transition relation::Example 1: First program, with no strengthenings. We have:ex1&Failed while establishing consecution.!Counter-example to inductiveness:& (S {x = -1, y = 1},S {x = 0, y = 0}),Example 2: First program, strengthened with x >= 0 . We have:ex2Q.E.D.;Example 3: Second program, with no strengthenings. We have:ex3&Failed while establishing consecution.!Counter-example to inductiveness:& (S {x = -1, y = 1},S {x = 0, y = 0})-Example 4: Second program, strengthened with x >= 0 . We have:ex4Failed while establishing consecution for strengthening "x >= 0".!Counter-example to inductiveness:( (S {x = 0, y = -1},S {x = -1, y = -1})-Example 5: Second program, strengthened with x >= 0 and y >= 1 separately. We have:ex5Failed while establishing consecution for strengthening "x >= 0".!Counter-example to inductiveness:( (S {x = 0, y = -1},S {x = -1, y = -1}) Note how this was sufficient in  to establish the invariant for the first program, but fails for the second.-Example 6: Second program, strengthened with x >= 0 /\ y >= 1 simultaneously. We have:ex6Q.E.D.Compare this to .. As pointed out by Bradley, this shows that a conjunction of assertions can be inductive when none of its components, on its own, is inductive. It remains an art to find proper loop invariants, though the science is improving!!'Queriable instance for our state  U(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone ':;< puzzle True Optimal model: Maximum model number = 96918996924991 :: Int64 ghci> puzzle False Optimal model: Minimum model number = 91811241911641 :: Int64 The program we need to crack. Note that different users get different programs on the Advent-Of-Code site, so this is simply one example. You can simply cut-and-paste your version instead. (Don't forget the pragma NegativeLiterals to GHC so add x -1 parses correctly as  add x (-1).) instance for . This is merely there for us to be able to represent programs in a natural way, i.e, lifting integers (positive and negative). Other methods are neither implemented nor needed.W(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone78?M3Days. Again, only the ones mentioned in the puzzle.Months. We only put in the months involved in the puzzle for simplicitySymbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor ."Represent the birthday as a recordSymbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .Make a valid symbolic birthdayIs this a valid birthday? i.e., one that was declared by Cheryl to be a possibility./Encode the conversation as given in the puzzle.NB. Lee Pike pointed out that not all the constraints are actually necessary! (Private communication.) The puzzle still has a unique solution if the statements a1 and b1 (i.e., Albert and Bernard saying they themselves do not know the answer) are removed. To experiment you can simply comment out those statements and observe that there still is a unique solution. Thanks to Lee for pointing this out! In fact, it is instructive to assert the conversation line-by-line, and see how the search-space gets reduced in each step.4Find all solutions to the birthday problem. We have:cheryl Solution #1: birthMonth = Jul :: Month birthDay = D16 :: DayThis is the only solution.X(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneR8 We will represent coins with 16-bit words (more than enough precision for coins).Create a coin. The argument Int argument just used for naming the coin. Note that we constrain the value to be one of the valid U.S. coin values as we create it.0Return all combinations of a sequence of values..Constraint 1: Cannot make change for a dollar.3Constraint 2: Cannot make change for half a dollar./Constraint 3: Cannot make change for a quarter.,Constraint 4: Cannot make change for a dime.-Constraint 5: Cannot make change for a nickelConstraint 6: Cannot buy the candy either. Here's where we need to have the extra knowledge that the vending machines do not take 50 cent coins.Solve the puzzle. We have:puzzleSatisfiable. Model: c1 = 50 :: Word16 c2 = 25 :: Word16 c3 = 10 :: Word16 c4 = 10 :: Word16 c5 = 10 :: Word16 c6 = 10 :: Word16 22 --> 33 --> 12 --> 31 --> 22 --> 33 --> 1Here's the contents in terms of gallons after each move: (8, 0, 0) (3, 5, 0) (3, 2, 3) (6, 2, 0) (6, 0, 2) (1, 5, 2) (1, 4, 3) (4, 4, 0)Note that by construction this is the minimum length solution. (Though our construction does not guarantee that it is unique.)  b(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone78?}U3Inhabitants of the island, as an uninterpreted sort-Each inhabitant is either a knave or a knightSymbolic version of the type .8Statements are utterances which are either true or falseSymbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$John is an inhabitant of the island.$Bill is an inhabitant of the island.The connective  makes a statement about an inhabitant regarding his/her identity.The connective 1 makes a predicate from what an inhabitant statesThe connective ) is will be true if the statement is trueThe connective * creates the conjunction of two statementsThe connective  negates a statementThe connective  creates a statement that equates the truth values of its argument statements"Encode Smullyan's puzzle. We have:puzzle Question 1. John says, We are both knaves Then, John is: Knave And, Bill is: Knight Question 2. John says If (and only if) Bill is a knave, then I am a knave.& Bill says We are of different kinds. Then, John is: Knave And, Bill is: Knightc(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone>Prints the only solution: ladyAndTigers Solution #1: sign1 = False :: Bool sign2 = False :: Bool sign3 = True :: Bool tiger1 = False :: Bool tiger2 = True :: Bool tiger3 = True :: BoolThis is the only solution.That is, the lady is in room 1, and only the third room's sign is true.d(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone/"The puzzle board is a list of rowsA row is a list of elementsUse 32-bit words for elements.4Checks that all elements in a list are within bounds#Get the diagonal of a square matrix'Test if a given board is a magic square3Group a list of elements in the sublists of length iGiven n, magic n prints all solutions to the nxn magic square probleme(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone'78?RolesSexes LocationsSymbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .Helper functorA person has a name, age, together with location and sex. We parameterize over a function so we can use this struct both in a concrete context and a symbolic context. Note that the name is always concrete.Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .Create a new symbolic person1Get the concrete value of the person in the modelSolve the puzzle. We have:killer&Alice 48 Bar Female Bystander#Husband 47 Beach Male Killer#Brother 48 Beach Male Victim&Daughter 21 Alone Female Bystander&Son 20 Bar Male BystanderThat is, Alice's brother was the victim and Alice's husband was the killer.Constraints of the puzzle, coded following the English description. Show a person$$f(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneA solution is a sequence of row-numbers where queens should be placed Checks that a given solution of n5-queens is valid, i.e., no queen captures any other.Given n, it solves the n-queens) puzzle, printing all possible solutions.g(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneEncoding of the constraints.,Print all solutions to the problem. We have: solvePuzzle Solution #1: a = 144 :: Integer b = 2 :: Integer c = True :: Bool d = 2 :: Integer e = False :: Bool f = 24 :: Integer g = False :: Bool h = -12 :: Integer i = True :: Bool( j = Right (-16) :: Either Bool IntegerThis is the only solution.h(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 78=? Location for each orangutan.Handlers for each orangutan.Orangutans in the puzzle.Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .'An assignment is solution to the puzzleSymbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .4Create a symbolic assignment, using symbolic fields.We get: allSat puzzle Solution #1:( Merah.handler = Gracie :: Handler) Merah.location = Tarakan :: Location( Merah.age = 10 :: Integer( Ofallo.handler = Eva :: Handler) Ofallo.location = Kendisi :: Location( Ofallo.age = 13 :: Integer( Quirrel.handler = Dolly :: Handler) Quirrel.location = Basahan :: Location( Quirrel.age = 4 :: Integer( Shamir.handler = Francine :: Handler) Shamir.location = Ambalat :: Location( Shamir.age = 7 :: IntegerThis is the only solution.&&i(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone78?A universe of rabbitsSymbolic version of the type .Identify those rabbits that are greedy. Note that we leave the predicate uninterpreted.Identify those rabbits that are black. Note that we leave the predicate uninterpreted.Identify those rabbits that are old. Note that we leave the predicate uninterpreted.Express the puzzle.Prove the claim. We have: rabbitsAreOKQ.E.D.j(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone2Solve the puzzle. We have: sendMoreMoney Solution #1: s = 9 :: Integer e = 5 :: Integer n = 6 :: Integer d = 7 :: Integer m = 1 :: Integer o = 0 :: Integer r = 8 :: Integer y = 2 :: IntegerThis is the only solution.That is:9567 + 1085 == 10652Truek(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneR Edge, Bono 2 <-- Bono 3 --> Larry, Adam 13 <-- Edge15 --> Edge, BonoTotal time: 17 Solution #2: 0 --> Edge, Bono 2 <-- Edge 4 --> Larry, Adam 14 <-- Bono15 --> Edge, BonoTotal time: 17 Found: 2 solutions with 5 moves.-Finding all possible solutions to the puzzle.Mergeable instance for  simply pushes the merging the data after run of each branch starting from the same state.,,n(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone#2Abduct extraction example. We have the constraint x >= 0 and we want to make  x + y >= 2 . We have:example6Got: (define-fun abd () Bool (and (= s0 s1) (= s0 1)))5Got: (define-fun abd () Bool (and (= 2 s1) (= s0 1)))7Got: (define-fun abd () Bool (and (= s0 s1) (<= 1 s1)))&Got: (define-fun abd () Bool (= 2 s1)) 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.o(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneFind all solutions to  x + y .== 10 for positive x and y3. This is rather silly to do in the query mode as   can do this automatically, but it demonstrates how we can dynamically query the result and put in new constraints based on those.Run the query. We have:demoStarting the all-sat engine! Iteration: 1Current solution is: (0,10) Iteration: 2Current solution is: (1,9) Iteration: 3Current solution is: (2,8) Iteration: 4Current solution is: (3,7) Iteration: 5Current solution is: (4,6) Iteration: 6Current solution is: (5,5) Iteration: 7Current solution is: (6,4) Iteration: 8Current solution is: (7,3) Iteration: 9Current solution is: (8,2) Iteration: 10Current solution is: (9,1) Iteration: 11Current solution is: (10,0) Iteration: 12No other solution![(0,10),(1,9),(2,8),(3,7),(4,6),(5,5),(6,4),(7,3),(8,2),(9,1),(10,0)]p(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneA simple floating-point problem, but we do the sat-analysis via a case-split. Due to the nature of floating-point numbers, a case-split on the characteristics of the number (such as NaN, negative-zero, etc. is most suitable.)We have:csDemo1 Case fpIsNegativeZero: Starting$Case fpIsNegativeZero: UnsatisfiableCase fpIsPositiveZero: Starting$Case fpIsPositiveZero: UnsatisfiableCase fpIsNormal: StartingCase fpIsNormal: UnsatisfiableCase fpIsSubnormal: Starting!Case fpIsSubnormal: UnsatisfiableCase fpIsPoint: StartingCase fpIsPoint: UnsatisfiableCase fpIsNaN: StartingCase fpIsNaN: Satisfiable("fpIsNaN",NaN)!Demonstrates the "coverage" case.We have:csDemo2Case negative: StartingCase negative: UnsatisfiableCase less than 8: StartingCase less than 8: UnsatisfiableCase Coverage: StartingCase Coverage: Satisfiable("Coverage",10)q/(c) Jeffrey Young Levent ErkokBSD3erkokl@gmail.com experimentalNonekFind all solutions to  x + y .== 10 for positive x and y, but at each iteration we would like to ensure that the value of x we get is at least twice as large as the previous one. This is rather silly, but demonstrates how we can dynamically query the result and put in new constraints based on those.In our first query we'll define a constraint that will not be known to the shared or second query and then solve for an answer that will differ from the first query. Note that we need to pass an MVar in so that we can operate on the shared variables. In general, the variables you want to operate on should be defined in the shared part of the query and then passed to the children queries via channels, MVars, or TVars. In this query we constrain x to be less than y and then return the sum of the values. We add a threadDelay just for demonstration purposesIn the second query we constrain for an answer where y is smaller than x, and then return the product of the found values.Run the demo several times to see that the children threads will change ordering.Example computation.In our first query we will make a constrain, solve the constraint and return the values for our variables, then we'll mutate the MVar sending information to the second query. Note that you could use channels, or TVars, or TMVars, whatever you need here, we just use MVars for demonstration purposes. Also note that this effectively creates an ordering between the children queriesIn 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 new variable and the old variables. Each child query is run in a separate instance of z3 so you can think of this query as driving to a point in the search space, then waiting for more information, once it gets that information it will run a completely separate computation from the first one and return its results.In our second demonstration we show how through the use of concurrency constructs the user can have children queries communicate with one another. Note that the children queries are independent and so anything side-effectual like a push or a pop will be isolated to that child thread, unless of course it happens in shared.r(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone78? 0Days of the week. We make it symbolic using the   splice.Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .A trivial query to find three consecutive days that's all before . The point here is that we can perform queries on such enumerated values and use  on them and return their values from queries just like any other value. We have:findDays[Monday,Tuesday,Wednesday]s(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone 78??Supported binary operators. To keep the search-space small, we will only allow division by 2 or 40, and exponentiation will only be to the power 0. This does restrict the search space, but is sufficient to solve all the instances.&Supported unary operators. Similar to  case, we will restrict square-root and factorial to be only applied to the value @4.Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .The shape of a tree, either a binary node, or a unary node, or the number 4', represented hear by the constructor F. We parameterize by the operator type: When doing symbolic computations, we'll fill those with  and . When finding the shapes, we will simply put unit values, i.e., holes.Symbolic version of the type .$Symbolic version of the constructor .$Symbolic version of the constructor .$Symbolic version of the constructor .Construct all possible tree shapes. The argument here follows the logic in  !http://www.gigamonkeys.com/trees/: We simply construct all possible shapes and extend with the operators. The number of such trees is:length allPossibleTrees640Note that this is a lot# smaller than what is generated by  !http://www.gigamonkeys.com/trees/. (There, the number of trees is 10240000: 16000 times more than what we have to consider!)Given a tree with hols, fill it with symbolic operators. This is the trick that allows us to consider only 640 trees as opposed to over 10 million.Minor helper for writing "symbolic" case statements. Simply walks down a list of values to match against a symbolic version of the key.Evaluate a symbolic tree, obtaining a symbolic value. Note how we structure this evaluation so we impose extra constraints on what values square-root, divide etc. can take. This is the power of the symbolic approach: We can put arbitrary symbolic constraints as we evaluate the tree.8In the query mode, find a filling of a given tree shape t2, such that it evaluates to the requested number i+. Note that we return back a concrete tree.Given an integer, walk through all possible tree shapes (at most 640 of them), and find a filling that solves the puzzle.Solution to the puzzle. When you run this puzzle, the solver can produce different results than what's shown here, but the expressions should still be all valid! ghci> puzzle 0 [OK]: (4 - (4 + (4 - 4))) 1 [OK]: (4 / (4 + (4 - 4))) 2 [OK]: sqrt((4 + (4 * (4 - 4)))) 3 [OK]: (4 - (4 ^ (4 - 4))) 4 [OK]: (4 + (4 * (4 - 4))) 5 [OK]: (4 + (4 ^ (4 - 4))) 6 [OK]: (4 + sqrt((4 * (4 / 4)))) 7 [OK]: (4 + (4 - (4 / 4))) 8 [OK]: (4 - (4 - (4 + 4))) 9 [OK]: (4 + (4 + (4 / 4))) 10 [OK]: (4 + (4 + (4 - sqrt(4)))) 11 [OK]: (4 + ((4 + 4!) / 4)) 12 [OK]: (4 * (4 - (4 / 4))) 13 [OK]: (4! + ((sqrt(4) - 4!) / sqrt(4))) 14 [OK]: (4 + (4 + (4 + sqrt(4)))) 15 [OK]: (4 + ((4! - sqrt(4)) / sqrt(4))) 16 [OK]: (4 * (4 * (4 / 4))) 17 [OK]: (4 + ((sqrt(4) + 4!) / sqrt(4))) 18 [OK]: -(4 + (4 - (sqrt(4) + 4!))) 19 [OK]: -(4 - (4! - (4 / 4))) 20 [OK]: (4 * (4 + (4 / 4))) A rudimentary # instance for trees, nothing fancy.t(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneԫUse the backend solver to guess the number given as argument. The number is assumed to be between 0 and 1000, and we use a simple binary search. Returns the sequence of guesses we performed during the search process.Play a round of the game, making the solver guess the secret number 42. Note that you can generate a random-number and make the solver guess it too! We have:play Current bounds: (0,1000)Current bounds: (21,1000)Current bounds: (31,1000)Current bounds: (36,1000)Current bounds: (39,1000)Current bounds: (40,1000)Current bounds: (41,1000)Current bounds: (42,1000)Solved in: 8 guesses: 8 21 31 36 39 40 41 42u(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneMathSAT example. Compute the interpolant for the following sets of formulas: {x - 3y >= -1, x + y >= 0}AND {z - 2x >= 3, 2z <= 1}where the variables are integers. Note that these sets of formulas are themselves satisfiable, but not taken all together. The pair (x, y) = (0, 0)# satisfies the first set. The pair (x, z) = (-2, 0)3 satisfies the second. However, there's no triple  (x, y, z) that satisfies all these four formulas together. We can use SBV to check this fact:sat $ \x y z -> sAnd [x - 3*y .>= -1, x + y .>= 0, z - 2*x .>= 3, 2 * z .<= (1::SInteger)] UnsatisfiableAn interpolant for these sets would only talk about the variable x" that is common to both. We have:!runSMTWith mathSAT exampleMathSAT "(<= 0 s0)"Notice that we get a string back, not a term; so there's some back-translation we need to do. We know that s0 is x through our translation mechanism, so the interpolant is saying that x >= 0 is entailed by the first set of formulas, and is inconsistent with the second. Let's use SBV to indeed show that this is the case:prove $ \x y -> (x - 3*y .>= -1 .&& x + y .>= 0) .=> (x .>= (0::SInteger))Q.E.D.And:prove $ \x z -> (z - 2*x .>= 3 .&& 2 * z .<= 1) .=> sNot (x .>= (0::SInteger))Q.E.D.4This establishes that we indeed have an interpolant!1Z3 example. Compute the interpolant for formulas y = 2x and y = 2z+1.These formulas are not satisfiable together since it would mean y is both even and odd at the same time. An interpolant for this pair of formulas is a formula that's expressed only in terms of y6, which is the only common symbol among them. We have:runSMT evenOdd"(let (a!1 (= (mod (+ (* (- 1) s1) 0) 2) 0)) (or (= s1 0) a!1))"This is a bit hard to read unfortunately, due to translation artifacts and use of strings. To analyze, we need to know that s1 is y through SBV's translation. Let's express it in regular infix notation with y for s1(, and substitute the let-bound variable: (y == 0) || ((-y) # 2 == 0)Notice that the only symbol is y, as required. To establish that this is indeed an interpolant, we should establish that when y is even, this formula is True ; and if y is odd, then it should be False. You can argue mathematically that this indeed the case, but let's just use SBV to prove the required relationships:prove $ \(y :: SInteger) -> (y `sMod` 2 .== 0) .=> ((y .== 0) .|| ((-y) `sMod` 2 .== 0))Q.E.D.And:prove $ \(y :: SInteger) -> (y `sMod` 2 .== 1) .=> sNot ((y .== 0) .|| ((-y) `sMod` 2 .== 0))Q.E.D.4This establishes that we indeed have an interpolant!v(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneA simple goal with three constraints, two of which are conflicting with each other. The third is irrelevant, in the sense that it does not contribute to the fact that the goal is unsatisfiable.Extract the unsat-core of  . We have:ucCore-Unsat core is: ["less than 5","more than 10"]"Demonstrating that the constraint a .> b is not) needed for unsatisfiablity in this case.w(c) Joel BurgetBSD3erkokl@gmail.com experimentalNone"9Solve a given crossword, returning the corresponding rowsSolve ;http://regexcrossword.com/challenges/intermediate/puzzles/1puzzle1 ["ATO","WEL"]Solve ;http://regexcrossword.com/challenges/intermediate/puzzles/2puzzle2["WA","LK","ER"]Solve ;http://regexcrossword.com/challenges/palindromeda/puzzles/3puzzle3["RATS","ABUT","TUBA","STAR"]x(c) Joel BurgetBSD3erkokl@gmail.com experimentalNone" Evaluation monad. The state argument is the environment to store variables as we evaluate.Simple expression language-Given an expression, symbolically evaluate itA simple program to query all messages with a given topic id. In SQL like notation:  query ("SELECT msg FROM msgs where topicid='" ++ my_topicid ++ "'")  findInjection exampleProgram "kg'; DROP TABLE 'users" though the topic might change obviously. Indeed, if we substitute the suggested string, we get the program: query ("SELECT msg FROM msgs WHERE topicid='kg'; DROP TABLE 'users'")which would query for topic kg! and then delete the users table!Here, we make sure that the injection ends with the malicious string:("'; DROP TABLE 'users" `Data.List.isSuffixOf`) <$> findInjection exampleProgramTrue6Literals strings can be lifted to be constant programsy(c) Brian SchroederBSD3erkokl@gmail.com experimentalNone)*:}Monad for querying a solver.The result of ing the combination of a  and a .$A property describes a quality of a  . It is a  yields a boolean value.A symbolic value representing the result of running a program -- its output.2A program that can reference two input variables, x and y.)Monad for performing symbolic evaluation.NOT (p OR (q AND r)) == (NOT p AND NOT q) OR (NOT p AND NOT r)>, following from the axioms we have specified above. We have:testQ.E.D.|(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneEAn uninterpreted function Asserts that f x z == f (y+2) z whenever x == y+2. Naturally correct: prove thmGoodQ.E.D.}(c) Levent ErkokBSD3erkokl@gmail.com experimentalNoneThe uninterpreted implementation of our 2x2 multiplier. We simply receive two 2-bit values, and return the high and the low bit of the resulting multiplication via two uninterpreted functions that we called mul22_hi and mul22_lo. Note that there is absolutely no computation going on here, aside from simply passing the arguments to the uninterpreted functions and stitching it back together.NB. While defining mul22_lo we used our domain knowledge that the low-bit of the multiplication only depends on the low bits of the inputs. However, this is merely a simplifying assumption; we could have passed all the arguments as well.Synthesize a 2x2 multiplier. We use 8-bit inputs merely because that is the lowest bit-size SBV supports but that is more or less irrelevant. (Larger sizes would work too.) We simply assert this for all input values, extract the bottom two bits, and assert that our "uninterpreted" implementation in ! is precisely the same. We have:sat synthMul22 Satisfiable. Model:2 mul22_hi :: Bool -> Bool -> Bool -> Bool -> Bool) mul22_hi False True True True = True) mul22_hi True True False True = True) mul22_hi True False True True = True) mul22_hi True False False True = True) mul22_hi False True True False = True) mul22_hi True True True False = True* mul22_hi _ _ _ _ = False" mul22_lo :: Bool -> Bool -> Bool mul22_lo True True = True mul22_lo _ _ = FalseIt is easy to see that the low bit is simply the logical-and of the low bits. It takes a moment of staring, but you can see that the high bit is correct as well: The logical formula is  a1b xor a0b1, and if you work out the truth-table presented, you'll see that it is exactly that. Of course, you can use SBV to prove this. First, let's define the function we have synthesized into a symbolic function::{ 1mul22_hi :: (SBool, SBool, SBool, SBool) -> SBoolmul22_hi params = params `sElem` [ (sFalse, sTrue, sTrue, sTrue) , (sTrue, sTrue, sFalse, sTrue) , (sTrue, sFalse, sTrue, sTrue) , (sTrue, sFalse, sFalse, sTrue) , (sFalse, sTrue, sTrue, sFalse) , (sTrue, sTrue, sTrue, sFalse)" ]:}Now we can say:prove $ \a1 a0 b1 b0 -> mul22_hi (a1, a0, b1, b0) .== (a1 .&& b0) .<+> (a0 .&& b1)Q.E.D.>and rest assured that we have a correctly synthesized circuit!~(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone A binary boolean functionA ternary boolean functionPositive Shannon cofactor of a boolean function, with respect to its first argumentNegative Shannon cofactor of a boolean function, with respect to its first argumentShannon's expansion over the first argument of a function. We have:shannonQ.E.D.Alternative form of Shannon's expansion over the first argument of a function. We have:shannon2Q.E.D.Computing the derivative of a boolean function (boolean difference). Defined as exclusive-or of Shannon cofactors with respect to that variable.The no-wiggle theorem: If the derivative of a function with respect to a variable is constant False, then that variable does not "wiggle" the function; i.e., any changes to it won't affect the result of the function. In fact, we have an equivalence: The variable only changes the result of the function iff the derivative with respect to it is not False:noWiggleQ.E.D.Universal quantification of a boolean function with respect to a variable. Simply defined as the conjunction of the Shannon cofactors.Show that universal quantification is really meaningful: That is, if the universal quantification with respect to a variable is True, then both cofactors are true for those arguments. Of course, this is a trivial theorem if you think about it for a moment, or you can just let SBV prove it for you:univOKQ.E.D.Existential quantification of a boolean function with respect to a variable. Simply defined as the conjunction of the Shannon cofactors.Show that existential quantification is really meaningful: That is, if the existential quantification with respect to a variable is True, then one of the cofactors must be true for those arguments. Again, this is a trivial theorem if you think about it for a moment, but we will just let SBV prove it:existsOKQ.E.D.  (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone78? A new data-type that we expect to use in an uninterpreted fashion in the backend SMT solver.Symbolic version of the type .5Declare an uninterpreted function that works over Q'sA satisfiable example, stating that there is an element of the domain  such that  returns a different element. Note that this is valid only when the domain $ has at least two elements. We have:t1Satisfiable. Model: x = Q_0 :: Q f :: Q -> Q f _ = Q_1This is a variant on the first example, except we also add an axiom for the sort, stating that the domain  has only one element. In this case the problem naturally becomes unsat. We have:t2 Unsatisfiable(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone78?A "list-like" data type, but one we plan to uninterpret at the SMT level. The actual shape is really immaterial for us.Symbolic version of the type .An uninterpreted "classify" function. Really, we only care about the fact that such a function exists, not what it does.Formulate a query that essentially asserts a cardinality constraint on the uninterpreted sort . The goal is to say there are precisely 3 such things, as it might be the case. We manage this by declaring four elements, and asserting that for a free variable of this sort, the shape of the data matches one of these three instances. That is, we assert that all the instances of the data  can be classified into 3 equivalence classes. Then, allSat returns all the possible instances, which of course are all uninterpreted.As expected, we have: allSat genLs Solution #1: l = L_2 :: L l0 = L_0 :: L l1 = L_1 :: L l2 = L_2 :: L classify :: L -> Integer classify L_2 = 2 classify L_1 = 1 classify _ = 0 Solution #2: l = L_1 :: L l0 = L_0 :: L l1 = L_1 :: L l2 = L_2 :: L classify :: L -> Integer classify L_2 = 2 classify L_1 = 1 classify _ = 0 Solution #3: l = L_0 :: L l0 = L_0 :: L l1 = L_1 :: L l2 = L_2 :: L classify :: L -> Integer classify L_2 = 2 classify L_1 = 1 classify _ = 0Found 3 different solutions. Levent ErkokBSD3erkokl@gmail.com experimentalNone#':;<=?> Helper type synonymThe state of the length program, paramaterized over the element type aOutputTemporary variableThe second input listThe first input list The imperative append algorithm:  zs = [] ts = xs while not (null ts) zs = zs ++ [head ts] ts = tail ts ts = ys while not (null ts) zs = zs ++ [head ts] ts = tail ts A program is the algorithm, together with its pre- and post-conditions.We check that zs is xs ++ ys upon termination. correctness!Total correctness is established.Q.E.D. instance for the program state>Show instance, a bit more prettier than what would be derived:  (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone':;<=?` Helper type synonym?The state for the swap program, parameterized over a base type a.Output Input valueThe increment algorithm:  y = x+1 The point here isn't really that this program is interesting, but we want to demonstrate various aspects of WP proofs. So, we take a before and after program to annotate our algorithm so we can experiment later.Precondition for our program. Strictly speaking, we don't really need any preconditions, but for example purposes, we'll require x to be non-negative.Postcondition for our program: y must equal x+1. Stability: x must remain unchanged.A program is the algorithm, together with its pre- and post-conditions.State the correctness with respect to before/after programs. In the simple case of nothing prior/after, we have the obvious proof:correctness Skip Skip!Total correctness is established.Q.E.D.!'Queriable instance for our stateShow instance for . The above deriving clause would work just as well, but we want it to be a little prettier here, and hence the OVERLAPS directive.  (c) Levent ErkokBSD3erkokl@gmail.com experimentalNone':;<=?"Helper type synonym>The state for the sum program, parameterized over a base type a.tracks fib itracks  fib (i+1) Loop counterThe input value#The imperative fibonacci algorithm:  i = 0 k = 1 m = 0 while i < n: m, k = k, m + k i++ When the loop terminates, m contains fib(n).Symbolic fibonacci as our specification. Note that we cannot really implement the fibonacci function since it is not symbolically terminating. So, we instead uninterpret and axiomatize it below.NB. The concrete part of the definition is only used in calls to = and is not needed for the proof. If you don't need to call <, you can simply ignore that part and directly uninterpret.Constraints and axioms we need to state explicitly to tell the SMT solver about our specification for fibonacci.Precondition for our program: n must be non-negative.Postcondition for our program:  m = fib n(Stability condition: Program must leave n unchanged.A program is the algorithm, together with its pre- and post-conditions.With the axioms in place, it is trivial to establish correctness: correctness!Total correctness is established.Q.E.D.Note that I found this proof to be quite fragile: If you do not get the algorithm right or the axioms aren't in place, z3 simply goes to an infinite loop, instead of providing counter-examples. Of course, this is to be expected with the quantifiers present.!'Queriable instance for our stateShow instance for . The above deriving clause would work just as well, but we want it to be a little prettier here, and hence the OVERLAPS directive.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone':;<=?+yHelper type synonym>The state for the sum program, parameterized over a base type a.Copy of y to be modifiedCopy of x to be modified Second value First value9The imperative GCD algorithm, assuming strictly positive x and y:  i = x j = y while i != j -- While not equal if i > j i = i - j -- i is greater; reduce it by j else j = j - i -- j is greater; reduce it by i When the loop terminates, i equals j and contains  GCD(x, y).Symbolic GCD as our specification. Note that we cannot really implement the GCD function since it is not symbolically terminating. So, we instead uninterpret and axiomatize it below.NB. The concrete part of the definition is only used in calls to = and is not needed for the proof. If you don't need to call , you can simply ignore that part and directly uninterpret. In that case, we simply use Prelude's version.Constraints and axioms we need to state explicitly to tell the SMT solver about our specification for GCD.Precondition for our program: x and y must be strictly positivePostcondition for our program: i == j and  i = gcd x y(Stability condition: Program must leave x and y unchanged.A program is the algorithm, together with its pre- and post-conditions.With the axioms in place, it is trivial to establish correctness: correctness!Total correctness is established.Q.E.D.Note that I found this proof to be quite fragile: If you do not get the algorithm right or the axioms aren't in place, z3 simply goes to an infinite loop, instead of providing counter-examples. Of course, this is to be expected with the quantifiers present.!'Queriable instance for our stateShow instance for . The above deriving clause would work just as well, but we want it to be a little prettier here, and hence the OVERLAPS directive.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone':;<=?4 Helper type synonymThe state for the division program, parameterized over a base type a. The remainder The quotient The divisor The dividend9The imperative division algorithm, assuming non-negative x and strictly positive y:  r = x -- set remainder to x q = 0 -- set quotient to 0 while y <= r -- while we can still subtract r = r - y -- reduce the remainder q = q + 1 -- increase the quotient 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.Precondition for our program: x must non-negative and y must be strictly positive. Note that there is an explicit call to  in our program to protect against this case, so if we do not have this precondition, all programs will fail.Postcondition for our program: Remainder must be non-negative and less than y, and it must hold that  x = q*y + r: Stability: x and y must remain unchanged.A program is the algorithm, together with its pre- and post-conditions.The invariant is simply that  x = q * y + r holds at all times and r$ is strictly positive. We need the y > 0 part of the invariant to establish the measure decreases, which is guaranteed by our precondition.The measure. In each iteration r0 decreases, but always remains positive. Since y is strictly positive, r% can serve as a measure for the loop.Check that the program terminates and the post condition holds. We have: correctness!Total correctness is established.Q.E.D. instance for the program stateShow instance for . The above deriving clause would work just as well, but we want it to be a little prettier here, and hence the OVERLAPS directive.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone':;<=?=Helper type synonymThe state for the division program, parameterized over a base type a.Successive odds%Successive squares, as the sum of j'sThe floor of the square root The input 0. part is needed to establish the termination.The measure. In each iteration i4 strictly increases, thus reducing the differential x - iCheck that the program terminates and the post condition holds. We have: correctness!Total correctness is established.Q.E.D.)'Queriable instance for the program stateShow instance for . The above deriving clause would work just as well, but we want it to be a little prettier here, and hence the OVERLAPS directive.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone '=?DHelper type synonymThe state of the length program, paramaterized over the element type aRunning length Copy of inputThe input list The imperative length algorithm:  ys = xs l = 0 while not (null ys) l = l+1 ys = tail ys 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.>Precondition for our program. Nothing! It works for all lists.Postcondition for our program: l& must be the length of the input list.(Stability condition: Program must leave xs unchanged.A program is the algorithm, together with its pre- and post-conditions.The invariant simply relates the length of the input to the length of the current suffix and the length of the prefix traversed so far.'The measure is obviously the length of ys1, as we peel elements off of it through the loop.We check that l! is the length of the input list xs upon termination. Note that even though this is an inductive proof, it is fairly easy to prove with our SMT based technology, which doesn't really handle induction at all! The usual inductive proof steps are baked into the invariant establishment phase of the WP proof. We have: correctness!Total correctness is established.Q.E.D.7Injection/projection from concrete and symbolic values.Show instance: A simplified version of what would otherwise be generated.(c) Levent ErkokBSD3erkokl@gmail.com experimentalNone':;<=?P Helper type synonym>The state for the sum program, parameterized over a base type a. Running sum Loop counterThe input value#The imperative summation algorithm: ; i = 0 s = 0 while i < n i = i+1 s = s+i 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.Precondition for our program: n? must be non-negative. Note that there is an explicit call to  in our program to protect against this case, so if we do not have this precondition, all programs will fail.Postcondition for our program: s5 must be the sum of all numbers up to and including n.(Stability condition: Program must leave n unchanged.A program is the algorithm, together with its pre- and post-conditions.&Check that the program terminates and s equals  n*(n+1)/26 upon termination, i.e., the sum of all numbers upto n . Note that this only holds if n >= 0 to start with, as guaranteed by the precondition of our program.#The correct termination measure is n-i9: It goes down in each iteration provided we start with n >= 0 and it always remains non-negative while the loop is executing. Note that we do not need a lexicographic measure in this case, hence we simply return a list of one element.>>>>>>>>>>>>>???? ????????????????@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@AAAAAABBBCCDEEEEEEEEEEEEEEEEEEEEEEEEEFFFGGGGGGGHHHHHIJKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMNOPQQQQQQQQRRRRRRRRRRRRRSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ[\\\\\\\\\\]]]^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^______________________````````````````````````aaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcddddddddeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeefffgghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhiiiiiiiiiiiiijkkkkkkkkkkkkkkllllllllmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnooppqqqqqqqqrrrrrrrrrrrrrrrrrrrrrrrrrssssssssssssssssssssssssssssssssssssssssssssssssttuuvvwwwwxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyzz{{{{{{{{{{{{||}}~~~~~~~~~ ~~~                      sbv-11.0-inplaceData.SBV.TransData.SBV.Trans.ControlData.SBVData.SBV.InternalsData.SBV.FloatData.SBV.RegExpData.SBV.DynamicData.SBV.ControlData.SBV.Tools.KnuckleDraggerData.SBV.Tools.GenTestData.SBV.TupleData.SBV.Tools.STreeData.SBV.Tools.PolynomialData.SBV.Tools.OverflowData.SBV.String Data.SBV.SetData.SBV.RationalData.SBV.Maybe Data.SBV.ListData.SBV.Either Data.SBV.CharData.SBV.Tools.CodeGen#Data.SBV.Tools.WeakestPreconditionsData.SBV.Tools.RangeData.SBV.Tools.NaturalInductionData.SBV.Tools.InductionData.SBV.Tools.BoundedListData.SBV.Tools.BoundedFixData.SBV.Tools.BVOptimizeData.SBV.Tools.BMC/Documentation.SBV.Examples.BitPrecise.BitTricks2Documentation.SBV.Examples.BitPrecise.BrokenSearch,Documentation.SBV.Examples.BitPrecise.Legato/Documentation.SBV.Examples.BitPrecise.MergeSort/Documentation.SBV.Examples.BitPrecise.PEXT_PDEP/Documentation.SBV.Examples.BitPrecise.PrefixSum0Documentation.SBV.Examples.CodeGeneration.AddSub2Documentation.SBV.Examples.CodeGeneration.CRC_USB53Documentation.SBV.Examples.CodeGeneration.Fibonacci-Documentation.SBV.Examples.CodeGeneration.GCD9Documentation.SBV.Examples.CodeGeneration.PopulationCount7Documentation.SBV.Examples.CodeGeneration.Uninterpreted%Documentation.SBV.Examples.Crypto.AES(Documentation.SBV.Examples.Crypto.Prince%Documentation.SBV.Examples.Crypto.RC4%Documentation.SBV.Examples.Crypto.SHA,Documentation.SBV.Examples.DeltaSat.DeltaSat3Documentation.SBV.Examples.Existentials.Diophantine3Documentation.SBV.Examples.KnuckleDragger.AppendRev0Documentation.SBV.Examples.KnuckleDragger.Basics3Documentation.SBV.Examples.KnuckleDragger.CaseSplit3Documentation.SBV.Examples.KnuckleDragger.Induction0Documentation.SBV.Examples.KnuckleDragger.Kleene1Documentation.SBV.Examples.KnuckleDragger.ListLen0Documentation.SBV.Examples.KnuckleDragger.RevLen;Documentation.SBV.Examples.KnuckleDragger.Sqrt2IsIrrational-Documentation.SBV.Examples.KnuckleDragger.Tao-Documentation.SBV.Examples.Lists.BoundedMutex4Documentation.SBV.Examples.Lists.CountOutAndTransfer*Documentation.SBV.Examples.Lists.Fibonacci)Documentation.SBV.Examples.Misc.Auxiliary+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.Newtypes&Documentation.SBV.Examples.Misc.NoDiv0+Documentation.SBV.Examples.Misc.Polynomials,Documentation.SBV.Examples.Misc.ProgramPaths*Documentation.SBV.Examples.Misc.SetAlgebra-Documentation.SBV.Examples.Misc.SoftConstrain%Documentation.SBV.Examples.Misc.Tuple1Documentation.SBV.Examples.Optimization.Enumerate0Documentation.SBV.Examples.Optimization.ExtField1Documentation.SBV.Examples.Optimization.LinearOpt2Documentation.SBV.Examples.Optimization.Production*Documentation.SBV.Examples.Optimization.VM-Documentation.SBV.Examples.ProofTools.AddHorn)Documentation.SBV.Examples.ProofTools.BMC/Documentation.SBV.Examples.ProofTools.Fibonacci0Documentation.SBV.Examples.ProofTools.Strengthen)Documentation.SBV.Examples.ProofTools.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.Jugs3Documentation.SBV.Examples.Puzzles.KnightsAndKnaves0Documentation.SBV.Examples.Puzzles.LadyAndTigers.Documentation.SBV.Examples.Puzzles.MagicSquare)Documentation.SBV.Examples.Puzzles.Murder*Documentation.SBV.Examples.Puzzles.NQueens,Documentation.SBV.Examples.Puzzles.Newspaper-Documentation.SBV.Examples.Puzzles.Orangutans*Documentation.SBV.Examples.Puzzles.Rabbits0Documentation.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.CaseSplit.Documentation.SBV.Examples.Queries.Concurrency(Documentation.SBV.Examples.Queries.Enums,Documentation.SBV.Examples.Queries.FourFours.Documentation.SBV.Examples.Queries.GuessNumber/Documentation.SBV.Examples.Queries.Interpolants,Documentation.SBV.Examples.Queries.UnsatCore1Documentation.SBV.Examples.Strings.RegexCrossword/Documentation.SBV.Examples.Strings.SQLInjection4Documentation.SBV.Examples.Transformers.SymbolicEval,Documentation.SBV.Examples.Uninterpreted.AUF/Documentation.SBV.Examples.Uninterpreted.Deduce1Documentation.SBV.Examples.Uninterpreted.Function1Documentation.SBV.Examples.Uninterpreted.Multiply0Documentation.SBV.Examples.Uninterpreted.Shannon-Documentation.SBV.Examples.Uninterpreted.Sort5Documentation.SBV.Examples.Uninterpreted.UISortAllSat6Documentation.SBV.Examples.WeakestPreconditions.Append6Documentation.SBV.Examples.WeakestPreconditions.Basics3Documentation.SBV.Examples.WeakestPreconditions.Fib3Documentation.SBV.Examples.WeakestPreconditions.GCD6Documentation.SBV.Examples.WeakestPreconditions.IntDiv7Documentation.SBV.Examples.WeakestPreconditions.IntSqrt6Documentation.SBV.Examples.WeakestPreconditions.Length3Documentation.SBV.Examples.WeakestPreconditions.SumsbvData.SBV.Control.TypessetLogiccheckSatcheckSatAssuminggetValue getUnsatCoregetUnknownReasonData.SBV.Core.AlgRealsData.SBV.SMT.SMTLibNamesData.SBV.Utils.ExtractIOControl.ConcurrentcatchesSWWriterTLWData.SBV.Utils.LibData.SBV.Core.KindGData $dmhasSign $dmintSizeOf$dmintSizeOf_$cshow $dmisArray $dmisBoolean $dmisBounded $dmisChar $dmisDouble $dmisEither$dmisFP $dmisFloat $dmisList $dmisMaybe $dmisRational $dmisReal$dmisSet $dmisString $dmisTuple$dmisUnbounded $dmisUserSort $dmkindOf $dmshowTypeData.SBV.Utils.NumericfpMinfpMaxData.SBV.Core.SizedFloatsData.SBV.Core.ConcreteData.SBV.Utils.TDiffData.SBV.Core.Symbolicz3yicescvc4 boolectormathSATallSatSymbolicQuerymatchRegExpMatchable svToSymSVgenTestsWordNsWordN_sIntNsIntN_ runSymbolicaddNewSMTOptionimposeConstraintaddSValOptGoalsObserve outputSVal Data.BitsBits Data.SBV.CoreSBV $dmqueryState$dmsymbolicEnvData.SBV.Core.OperationsSFloatSWord32SDoubleSWord64Data.SBV.Core.SizedData.SBV.Core.DatafpIsEqualObjectmkSymValfreefree_ mkFreeVarssymbolic symbolicsoutputtimeOutSetmkSymSBV sbvToSymSW EqSymbolic$dm./=$dm./==$dm.==$dm.=== $dmallEqual $dmallEqual1 $dmdistinct$dmdistinctExcept$dmfree$dmfree_ $dmfromCV $dmisConcrete$dmisConcretely $dmisSymbolic $dmliteral $dmmkFreeVars $dmmkSymVal$dmsElem $dmsNotElem $dmsetInfo $dmsetLogic $dmsetTimeOut $dmskolemize $dmsymbolic $dmsymbolics$dmtaggedSkolemize $dmunliteral432615Data.SBV.Utils.SExprData.SBV.Utils.PrettyNumData.SBV.Utils.CrackNumData.SBV.SMT.UtilsData.SBV.SMT.SMTLib2 registerKindData.SBV.SMT.SMTLibData.SBV.SMT.SMToptimizesafesatprove $dmcvtModel$dmextractModel$dmgetModelObjectiveValue$dmgetModelUIFunValue$dmgetModelUninterpretedValue$dmgetModelValue $dmparseCVsData.SBV.Provers.Z3Data.SBV.Provers.YicesData.SBV.Provers.OpenSMTData.SBV.Provers.MathSATData.SBV.Provers.DRealData.SBV.Provers.CVC5Data.SBV.Provers.CVC4Data.SBV.Provers.BoolectorData.SBV.Provers.BitwuzlaData.SBV.Provers.ABCData.SBV.LambdaData.SBV.Control.UtilssAssertiomodifyQueryState inNewContext freshVar_freshVar queryDebugasksendretrieveResponse getFunctiongetUninterpretedValue getValueCV getUICValgetUIFunCVAssoc checkSatUsingobservegetUIsgetUnsatAssumptionstimeout unexpected executeQueryQueryT $dmsexprToFun$dmsexprToFun1$dmsmtFunDefault $dmsmtFunNameData.SBV.Control.QuerygetInfo ensureSat getSMTResultgetLexicographicOptResultsgetIndependentOptResultsgetParetoOptResultsgetModel$checkSatAssumingWithUnsatisfiableSetgetAssertionStackDepthinNewAssertionStackpushpop caseSplitresetAssertionsechoexitgetProofgetInterpolantMathSAT getAbduct getAbductNextgetInterpolantZ3 getAssertions getAssignment mkSMTResultData.SBV.Provers.ProversNamesafeWith proveWithdprove dproveWithisVacuousProofisVacuousProofWith isTheorem isTheoremWithsatWith allSatWith isSatisfiableisSatisfiableWith optimizeWithData.SBV.Provers SatisfiablerunSMT runSMTWith $dmallSat $dmallSatWith $dmdprove $dmdproveWith$dmdsat $dmdsatWith$dmisSatisfiable$dmisSatisfiableWith $dmisTheorem$dmisTheoremWith$dmisVacuousProof$dmisVacuousProofWith $dmoptimize$dmoptimizeWith$dmprove $dmproveWith$dmsafe $dmsafeWith$dmsat $dmsatWithData.SBV.Tools.KDUtilsData.SBV.Core.ModelregisterUISMTFunctionGenericStatus genMkSymVarsBoolsBool_sBoolssWord8sWord8_sWord8ssWord16sWord16_sWord16ssWord32sWord32_sWord32ssWord64sWord64_sWord64ssInt8sInt8_sInt8ssInt16sInt16_sInt16ssInt32sInt32_sInt32ssInt64sInt64_sInt64ssInteger sInteger_ sIntegerssRealsReal_sRealssFloatsFloat_sFloatssDoublesDouble_sDoublessFPHalfsFPHalf_sFPHalfs sFPBFloat sFPBFloat_ sFPBFloats sFPSingle sFPSingle_ sFPSingles sFPDouble sFPDouble_ sFPDoublessFPQuadsFPQuad_sFPQuadssFloatingPointsFloatingPoint_sFloatingPointssWordsWord_sIntsInt_sIntssCharsChar_sCharssStringsString_sStringssListsList_sListssAraysTuplesTuple_sTuples sRational sRational_ sRationalssEithersEither_sEitherssMaybesMaybe_sMaybessSetsolveGenericsassertWithPenaltyminimizemaximizedReal$dm.<=$dm.>$dm.>=$dmannotateForMS $dmblastBE $dmblastLE$dmcgUninterpret $dmfromBitsBE $dmfromBitsLE$dmfromBitsLE_$csetBit$dmfromBitsLE_$csymbolicMerge$dmfromMetricSpace $dmfullAdder$dmfullAdder_$c.>$dmfullMultiplier $dminRange$dmlsb $dmmsMaximize $dmmsMinimize$dmmsb$dmsCountLeadingZeros$dmsCountLeadingZeros_$cliteral$dmsCountTrailingZeros$dmsDiv$dmsExtractBits$dmsMod $dmsPopCount$dmsQuot$dmsRem $dmsSetBitTo $dmsTestBit $dmselect$dmselect_$c.< $dmsetBitTo$dmsmax$dmsmin$dmsmtFunction$dmsym$dmsymbolicMerge$dmtoMetricSpace$dmuninterpret$dmuninterpretWithArgs8$dmpAdd$dmpDiv$dmpMod $dmpolynomial $dmshowPoly7nullisFull difference9zipWithfoldlData.SBV.Core.Floating$dmfpAbs$dmfpAdd$dmfpDiv$dmfpFMA$dmfpIsEqualObject$dmfpIsInfinite $dmfpIsNaN$dmfpIsNegative$dmfpIsNegativeZero $dmfpIsNormal $dmfpIsPoint$dmfpIsPositive$dmfpIsPositiveZero$dmfpIsSubnormal $dmfpIsZero$dmfpMax$dmfpMin$dmfpMul$dmfpNeg$dmfpRem$dmfpRoundToIntegral $dmfpSqrt$dmfpSub$dmfromSDouble $dmfromSFloat$dmfromSFloatingPoint $dmtoSDouble $dmtoSFloat$dmtoSFloatingPointData.SBV.ClientData.SBV.Control.BaseIOProduceUnsatCores getOptiongetObservablesUnsat setOptionProduceUnsatAssumptionsnamedConstraint OptionKeyword ProduceProofsProduceInterpolantsconstrainWithAttributeProduceAssertionsProduceAssignmentsverboseredirectVerboseData.SBV.Compilers.CodeGen compileToCLibData.SBV.Compilers.CData.SBV.Client.BaseIOdsat defaultSMTCfgallSatMaxModelCountsName_ sbvToSymSVsWords SFPBFloatSEither SRationalSMaybeSSetsSet_sSetssArraysArray_sArrays $dmfromSized $dmtoSized$dmembed $dmprojectData.SBV.Tools.KDKernel $dminductAlt1 $dminductAlt2$dmchainGeneric $dmchainLemma$dmchainLemmaWith$dmchainTheorem$dmchainTheoremWith Data.SBV.SMTgetModelDictionaries isNonModelVal Control.MonadwhenabortLogicAUFLIAAUFLIRAAUFNIRALRAQF_ABVQF_AUFBV QF_AUFLIAQF_AXQF_BVQF_IDLQF_LIAQF_LRAQF_NIAQF_NRAQF_RDLQF_UFQF_UFBVQF_UFIDLQF_UFLIAQF_UFLRAQF_UFNRA QF_UFNIRAUFLRAUFNIAQF_FPBVQF_FPQF_FDQF_S Logic_ALL Logic_NONE CustomLogic SMTOptionDiagnosticOutputChannelProduceAbducts RandomSeedReproducibleResourceLimit SMTVerbositySetLogicSetInfoSMTInfoResponseResp_UnsupportedResp_AllStatisticsResp_AssertionStackLevels Resp_Authors Resp_Error Resp_NameResp_ReasonUnknown Resp_VersionResp_InfoKeywordSMTReasonUnknown UnknownMemOutUnknownIncompleteUnknownTimeOut UnknownOtherSMTErrorBehaviorErrorImmediateExitErrorContinuedExecution SMTInfoFlag AllStatisticsAssertionStackLevelsAuthors ErrorBehaviorName ReasonUnknownVersion InfoKeywordCheckSatResultSatDSatUnk RationalCVRatIrreducibleRatExact RatApprox RatInterval AlgRealPolyAlgReal AlgRational AlgPolyRoot AlgInterval RealPoint OpenPoint ClosedPoint realPointalgRealToRationalsmtLibReservedNames ExtractIO extractIO RoundingModeRoundNearestTiesToEvenRoundNearestTiesToAwayRoundTowardPositiveRoundTowardNegativeRoundTowardZero ValidFloat BVIsNonZeroHasKindkindOfhasSign intSizeOf isBoolean isBoundedisRealisFloatisDouble isRationalisFP isUnbounded isUserSortisCharisStringisListisSetisTupleisMaybeisEitherisArrayshowTypeKindKBoolKBounded KUnboundedKReal KUserSortKFloatKDoubleKFPKCharKStringKListKSetKTupleKMaybe KRationalKEitherKArraysmtRoundingModefpMaxHfpMinHfp2fpfpRemHfpRoundToIntegralHfpIsEqualObjectHfpCompareObjectHfpIsNormalizedH floatToWord wordToFloat doubleToWord wordToDoubleFPfpValuefpSignificandSizefpExponentSizeFPQuadFPDoubleFPSingleFPBFloatFPHalf FloatingPointfpFromBigFloat fpFromRawRepfpNaNfpInffpZero fpFromIntegerfpFromRational fpEncodeFloat fpFromFloat fpFromDoubleExtCVInfiniteEpsilonInterval BoundedCVAddExtCVMulExtCV GeneralizedCV ExtendedCV RegularCVCVcvVal_cvKindCValCAlgRealCIntegerCFloatCDoubleCFP CRationalCCharCStringCListCSet CUserSortCTupleCMaybeCEitherCArray ArrayModelRCSet RegularSet ComplementSet isRegularCV cvSameTypecvToBoolnormCVfalseCVtrueCVmapCVmapCV2 mkConstCVTimingNoTiming PrintTiming SaveTiming showTDiff QueryContext QueryInternal QueryExternal SMTSolver capabilitiesengineoptions preprocess executablenameSolverABC BoolectorBitwuzlaCVC4CVC5DRealMathSATYicesZ3OpenSMT SMTScript scriptModel scriptBody SMTResult UnsatisfiableDeltaSat SatExtFieldUnknown ProofErrorSMTModel modelUIFuns modelAssocs modelBindingsmodelObjectives SMTConfigkdRibbonLengthignoreExitCodesolverSetOptions roundingMode extraArgssolver dsatPrecision smtLibVersion transcriptoptimizeValidateConstraints validateModel isNonModelVarallSatTrackUFsallSatPrintAlongsatCmdcrackNumSurfaceValscrackNum printRealPrec printBasetimingSolverCapabilitiessupportsFlattenedModelssupportsDirectAccessorssupportsSpecialRelssupportsFoldAndMapsupportsDataTypessupportsGlobalDeclssupportsCustomQueriessupportsPseudoBooleanssupportsOptimization supportsSetssupportsIEEE754supportsDeltaSatsupportsApproxReals supportsRealssupportsInt2bvsupportsUnboundedIntssupportsUninterpretedSortssupportsBitVectorssupportsDistinctsupportsDefineFunsupportsQuantifiers SMTLibPgm SMTLibVersionSMTLib2Cached SymbolicT MonadSymbolic symbolicEnv UICodeKindUINoneUISMTUICgCSValState SBVRunModeSMTModeCodeGen LambdaGenConcreteIStageISetupISafeIRunResult resOutputs resAssertionsresConstraintsresAsgnsresDefinitions resUIConsts resTables resConsts resParams resUISegsresObservables resTracesreskindsprogInfo runQueryT MonadQuery queryState QueryStatequeryAssertionStackDepthqueryTimeOutValuequeryTerminate queryConfigqueryRetrieveResponse querySendqueryAsk ObjectiveMinimizeMaximizeAssertWithPenaltyPenaltyDefaultPenalty OptimizeStyle Lexicographic IndependentPareto NamedSymVarSBVPgmpgmAssignmentsSBVExprSBVAppSBVType VarContext NonQueryVarQueryVar QuantifierALLEXSeqOp SeqConcatSeqLenSeqUnitSeqNth SeqSubseq SeqIndexOf SeqContains SeqPrefixOf SeqSuffixOf SeqReplaceSeqMapSeqMapI SeqFoldLeft SeqFoldLeftI SBVReverseRegExpLiteralAllAllCharNoneRangeConcKStarKPlusOptCompDiffLoopPowerUnionInterRegExOpRegExEqRegExNEqStrOp StrConcatStrLenStrUnitStrNth StrSubstr StrIndexOf StrContains StrPrefixOf StrSuffixOf StrReplace StrStrToNat StrNatToStr StrToCode StrFromCodeStrInReOvOpPlusOvSubOvMulOvDivOvNegOvPBOp PB_AtMost PB_AtLeast PB_ExactlyPB_LePB_GePB_EqFPOpFP_CastFP_ReinterpretFP_AbsFP_NegFP_AddFP_SubFP_MulFP_DivFP_FMAFP_SqrtFP_RemFP_RoundToIntegralFP_MinFP_Max FP_ObjEqual FP_IsNormalFP_IsSubnormal FP_IsZero FP_IsInfiniteFP_IsNaN FP_IsNegative FP_IsPositiveOpPlusTimesMinusUNegAbsQuotRemEqualImpliesNotEqualLessThan GreaterThanLessEq GreaterEqIteAndOrXOrNotShlShrRolRorDividesExtractJoin ZeroExtend SignExtendLkUpKindCast UninterpretedQuantifiedBool SpecialRelOpLabelIEEEFP NonLinear OverflowOp PseudoBooleanSetOpTupleConstructor TupleAccessEitherConstructorEitherIs EitherAccessRationalConstructorMaybeConstructorMaybeIs MaybeAccess ArrayLambda ReadArray WriteArraySVNodeIdgetId forceSVArgfalseSVtrueSVneedsExistentials isCodeGenMode inSMTModesvUninterpretednewUninterpretedinternalVariable getTableIndexnewExprsvToSV svMkSymVar mkNewStateextractSymbolicSimulationStateinternalConstraintcacheuncachesmtLibVersionExtensionsvTruesvFalsesvBool svIntegersvFloatsvDoublesvFloatingPointsvRealsvAsBool svAsInteger svNumerator svDenominatorsvEnumFromThenTosvPlussvTimessvMinussvUNegsvAbssvDividesvExp svBlastLEsvSetBit svBlastBE svWordFromLE svWordFromBE svAddConstant svIncrement svDecrementsvQuotsvRem svQuotRem svStrongEqualsvEqual svNotEqual svLessThan svGreaterThansvLessEq svGreaterEqsvAndsvOrsvXOrsvNotsvShlsvShrsvRolsvRor svExtractsvJoin svZeroExtend svSignExtendsvIte svLazyItesvSymbolicMergesvSelectsvSignsvUnsignsvFromIntegral svToWord1 svFromWord1 svTestBit svShiftLeft svShiftRightsvBarrelRotateLeftsvBarrelRotateRight svRotateLeft svRotateRightsvStructuralLessThansvFloatingPointAsSWordIntNWordNQNot NegatesToqNot Skolemize SkolemsTo skolemizetaggedSkolemize.==./=.===./==distinctdistinctExceptallEqualsElemsNotElemSymValliteralfromCV isConcretely unliteral isConcrete isSymbolic Outputtable SolverContext constrain softConstrainsetInfo setTimeOut contextStatequantifiedBoolLambdamkLambdaForallNExistsNForall ExistsUniqueExists Constraint mkConstraint SRoundingMode SMTProblem smtLibPgmSTuple8STuple7STuple6STuple5STuple4STuple3STuple2STupleSArraySListSStringSCharSIntSWordSFPQuad SFPDouble SFPSingleSFPHalfSFloatingPointSRealSIntegerSInt64SInt32SInt16SInt8SWord16SWord8SBoolunSBVgetPathConditionextendPathConditionnaninfinitysNaN sInfinitysTruesFalsesNot.&&.||.<+>.~&.~|.=>.<=>fromBoolsAndsOrsAnysAllsRoundNearestTiesToEvensRoundNearestTiesToAwaysRoundTowardPositivesRoundTowardNegativesRoundTowardZerosRNEsRNAsRTPsRTNsRTZsbvToSV bvExtract#bvDropbvTake PrettyNumhexSbinShexPbinPhexbinshexchexshexIsbinsbinIreadBin showCFloat showCDouble showHFloat showHDouble showSMTFloat showSMTDouble cvToSMTLib showBFloatshowFloatAtBaseshowNegativeNumber SBVExceptionsbvExceptionHintsbvExceptionReasonsbvExceptionConfigsbvExceptionExitCodesbvExceptionStdErrsbvExceptionStdOutsbvExceptionReceivedsbvExceptionExpectedsbvExceptionSentsbvExceptionDescription Modelable modelExistsgetModelAssignmentgetModelDictionary getModelValuegetModelUninterpretedValue extractModelgetModelObjectivesgetModelObjectiveValuegetModelUIFunsgetModelUIFunValueSatModelparseCVscvtModelOptimizeResultLexicographicResult ParetoResultIndependentResult SafeResult AllSatResult allSatResultsallSatSolverReturnedDSatallSatSolverReturnedUnknownallSatMaxModelCountReached SatResult ThmResultgenParse extractModelsgetModelValuesgetModelUninterpretedValues displayModels showModellambda lambdaStr namedLambdanamedLambdaStr constraint constraintStrregisterSMTType|->query SExecutable ProvableMproofArgReduce SatisfiableM satArgReducedsatWithProvable ConstraintSet Predicateabcbitwuzlacvc5openSMTdefaultDeltaSMTCfg satWithAll satWithAnysatConcurrentWithAnysatConcurrentWithAll proveWithAny proveWithAllproveConcurrentWithAnyproveConcurrentWithAllgenerateSMTBenchmarkSatgenerateSMTBenchmarkProofisSafeKDrunKD runKDWith TestStyleHaskellCForte TestVectors getTestValues renderTestEquality===Metric MetricSpace toMetricSpacefromMetricSpace annotateForMS msMinimize msMaximize SMTDefinable smtFunction uninterpretuninterpretWithArgs cgUninterpretsbvDefineValuesymsbv2smt Mergeable symbolicMergeselect SDivisiblesQuotRemsDivModsQuotsRemsDivsMod SFiniteBitssFiniteBitSizelsbmsbblastBEblastLE fromBitsBE fromBitsLEsTestBit sExtractBits sPopCountsetBitTo sSetBitTo fullAdderfullMultipliersCountLeadingZerossCountTrailingZeros SIntegral OrdSymbolic.<.<=.>.>=sminsmaxinRangeSymTuple genLiteral genFromCVsRealToSIntegerlabel observeIf zeroExtend signExtendoneIfpbAtMost pbAtLeast pbExactlypbLepbGepbEq pbMutexedpbStronglyMutexed.^ sFromIntegral sShiftLeft sShiftRightsSignedShiftArithRight sRotateLeftsBarrelRotateLeft sRotateRightsBarrelRotateRightsDividesliftQRemliftDModsEDivModsEDivsEModiteiteLazy sbvQuickCheck readArray writeArray lambdaArray listArrayuntupletuple^.swap_1_2_3_4_5_6_7_8$fMetricTuple8$fMetricTuple7$fMetricTuple6$fMetricTuple5$fMetricTuple4$fMetricTuple3$fMetricTuple2$fHasField"_8"hTuple8$fHasField"_7"gTuple8$fHasField"_7"gTuple7$fHasField"_6"fTuple8$fHasField"_6"fTuple7$fHasField"_6"fTuple6$fHasField"_5"eTuple8$fHasField"_5"eTuple7$fHasField"_5"eTuple6$fHasField"_5"eTuple5$fHasField"_4"dTuple8$fHasField"_4"dTuple7$fHasField"_4"dTuple6$fHasField"_4"dTuple5$fHasField"_4"dTuple4$fHasField"_3"cTuple8$fHasField"_3"cTuple7$fHasField"_3"cTuple6$fHasField"_3"cTuple5$fHasField"_3"cTuple4$fHasField"_3"cTuple3$fHasField"_2"bTuple8$fHasField"_2"bTuple7$fHasField"_2"bTuple6$fHasField"_2"bTuple5$fHasField"_2"bTuple4$fHasField"_2"bTuple3$fHasField"_2"bTuple2$fHasField"_1"aTuple8$fHasField"_1"aTuple7$fHasField"_1"aTuple6$fHasField"_1"aTuple5$fHasField"_1"aTuple4$fHasField"_1"aTuple3$fHasField"_1"aTuple2$fTupleTuple8Tuple8$fTupleTuple7Tuple7$fTupleTuple6Tuple6$fTupleTuple5Tuple5$fTupleTuple4Tuple4$fTupleTuple3Tuple3$fTupleTuple2Tuple2STree readSTree writeSTreemkSTree$fMergeableSTreeInternal$fShowSTreeInternal Polynomial polynomialpAddpMultpDivpModpDivModshowPolyshowPolynomialaddPolyitesmdpcrcBVcrc$fPolynomialSBV$fPolynomialSBV0$fPolynomialSBV1$fPolynomialSBV2$fPolynomialSBV3$fPolynomialWord64$fPolynomialWord32$fPolynomialWord16$fPolynomialWord8CheckedArithmetic+!-!*!/! negateChecked ArithOverflowbvAddObvSubObvMulObvDivObvNegOsFromIntegralOsFromIntegralCheckedsignedMulOverflow$fArithOverflowSVal$fArithOverflowSBV$fArithOverflowSBV0$fArithOverflowSBV1$fArithOverflowSBV2$fArithOverflowSBV3$fArithOverflowSBV4$fArithOverflowSBV5$fArithOverflowSBV6$fArithOverflowSBV7$fArithOverflowSBV8$fCheckedArithmeticIntN$fCheckedArithmeticWordN$fCheckedArithmeticInt64$fCheckedArithmeticInt32$fCheckedArithmeticInt16$fCheckedArithmeticInt8$fCheckedArithmeticWord64$fCheckedArithmeticWord32$fCheckedArithmeticWord16$fCheckedArithmeticWord8lengthheadtailunconsinit singleton strToStrAt strToCharAt!!implode.:snocnilconcat++ isInfixOf isPrefixOf isSuffixOftakedropsubStrreplaceindexOf offsetIndexOfreversestrToNatnatToStremptyfull universalfromList complementinsertdeletemember notMemberisEmpty isUniversal isSubsetOfisProperSubsetOfdisjointunionunions intersection intersections\\.%sNothing isNothingsJustisJust fromMaybefromJust liftMaybemapmap2maybe$fNumSBV listToListAtelemAtelemnotElemsubListmapifoldlifoldrfoldrizipallanyfiltersLeftisLeftsRightisRight liftEithereitherbimapfirstsecondfromLeft fromRightIEEEFloatConvertible fromSFloattoSFloat fromSDouble toSDoublefromSFloatingPointtoSFloatingPoint IEEEFloatingfpAbsfpNegfpAddfpSubfpMulfpDivfpFMAfpSqrtfpRemfpRoundToIntegral fpIsNormal fpIsSubnormalfpIsZero fpIsInfinitefpIsNaN fpIsNegative fpIsPositivefpIsNegativeZerofpIsPositiveZero fpIsPointsFloatAsSWord32sDoubleAsSWord64 blastSFloat blastSDoubleblastSFloatingPointsWord32AsSFloatsWord64AsSDoublesFloatAsComparableSWord32sDoubleAsComparableSWord64sFloatingPointAsSWordsFloatingPointAsComparableSWordsWordAsSFloatingPointordchr toLowerL1 toUpperL1 digitToInt intToDigit isControlL1 isSpaceL1 isLowerL1 isUpperL1 isAlphaL1 isAlphaNumL1 isPrintL1isDigit isOctDigit isHexDigit isLetterL1isMarkL1 isNumberL1isPunctuationL1 isSymbolL1 isSeparatorL1isAsciiisLatin1 isAsciiUpper isAsciiLower everythingnothinganyCharexactlyoneOfnewlinetabwhiteSpaceNoNewLine whiteSpace punctuation asciiLetter asciiLower asciiUpperdigitoctDigithexDigitdecimaloctal hexadecimalfloating identifier$fRegExpMatchableSBV$fRegExpMatchableSBV0sbvCheckSolverInstallationdefaultSolverConfiggetAvailableSolversmkSymbolicEnumerationmkUninterpretedSort CgPgmKind CgMakefileCgHeaderCgSourceCgDriver CgPgmBundle CgSRealTypeCgFloatCgDouble CgLongDouble SBVCodeGenCgState cgFinalConfig cgLDFlagscgDecls cgPrototypes cgReturns cgOutputscgInputsCgValCgAtomicCgArrayCgConfig cgShowU8InHexcgOverwriteGeneratedcgIgnoreAsserts cgGenMakefile cgGenDriver cgDriverValscgReal cgIntegercgRTCCgTarget targetName translatedefaultCgConfig initCgStatecgSym cgPerformRTCs cgIntegerSize cgSRealTypecgGenerateDrivercgGenerateMakefilecgSetDriverValuescgIgnoreSAssertcgAddPrototypecgOverwriteFilescgShowU8UsingHex cgAddDecl cgAddLDFlags svCgInput svCgInputArr svCgOutput svCgOutputArr svCgReturn svCgReturnArrcgInput cgInputArrcgOutput cgOutputArrcgReturn cgReturnArr isCgDriver isCgMakefilecodeGenrenderCgPgmBundle compileToC compileToC'compileToCLib'sendStringToSolverretrieveResponseFromSolversendRequestToSolversComparableSWord32AsSFloatsComparableSWord64AsSDouble sComparableSWordAsSFloatingPointtoSizedToSized fromSized FromSized partition Queriable QueryResultcreateprojectembedRelation ByteConvertertoBytes fromBytescrackisPartialOrder isLinearOrder isTreeOrderisPiecewiseLinearOrdermkTransitiveClosureoptLexicographicoptLexicographicWith optPareto optParetoWithoptIndependentoptIndependentWith$fByteConverterSBV$fByteConverterSBV0$fByteConverterSBV1$fByteConverterSBV2$fByteConverterSBV3$fByteConverterSBV4$fByteConverterSBV5$fByteConverterSBV6$fQueriablemSBVGoodStuckWPConfig wpVerbosewpSolver ProofResultProven IndeterminateFailedVCBadPreconditionBadPostconditionUnstableAbortReachable InvariantPreInvariantMaintain MeasureBoundMeasureDecreaseStmtSkipAbortAssignIfWhileSeqMeasure InvariantStableProgram stability postconditionprogram preconditionsetupassertstable wpProveWithwpProve defaultWPCfgtraceExecution$fShowVC$fShowProofResult $fShowStatusBoundary UnboundedOpenClosedranges rangesWith $fShowRange inductNat inductNatWith Inductioninduct inductAlt1 inductAlt2Proof Propositionaxiomsorrylemma lemmaWiththeorem theoremWith chainLemma chainTheoremchainLemmaWithchainTheoremWith$fChainLemmaFUNFUN$fChainLemmaFUNFUN0$fChainLemmaFUNFUN1$fChainLemmaFUNFUN2$fChainLemmaFUNFUN3$fChainLemmaFUNFUN4$fChainLemmaFUNFUN5$fChainLemmaFUNFUN6$fChainLemmaFUNFUN7$fChainLemmaFUNFUN8InductionResult InductionStep Initiation ConsecutionPartialCorrectness inductWith$fShowInductionStep$fShowInductionResultbfoldrbfoldrMbfoldlbfoldlMbsumbprodbmapbmapMbfilterbandborbanyballbmaximumbminimumbzipWithbelembreversebsortbfixmaxBV maxBVWithminBV minBVWith bmcRefute bmcRefuteWithbmcCover bmcCoverWith svQuickChecksvNewVar svNewVar_fastMinCorrectfastMaxCorrectoppositeSignsCorrectconditionalSetClearCorrectpowerOfTwoCorrectqueriesmidPointBroken midPointFixedmidPointAlternativecheckArithOverflowcheckCorrectMidValueInitVals InstructionMostekflags registersmemoryMemoryLocationF1F2LOFlags RegistersBitValueFlagFlagCFlagZRegisterRegXRegAgetRegsetReggetFlagsetFlagpeekpoke checkOverflowcheckOverflowCorrectldxldaclcrorMrorRbccadcdexbneendlegato runLegato initMachinelegatoIsCorrectcorrectnessTheorem legatoInC$fGenericMostek$fMergeableMostek $fEqLocation $fOrdLocation $fIxLocation$fBoundedLocation$fEqFlag $fOrdFlag$fIxFlag $fBoundedFlag $fEqRegister $fOrdRegister $fIxRegister$fBoundedRegisterEmerge mergeSort nonDecreasingisPermutationOf correctnesspextpdepextractThenDepositdepositThenExtractpext_2 PowerListtiePLzipPLunzipPLpslf flIsCorrectthm1thm2addSub genAddSubusb5crcUSBcrcUSB'crcGoodcg1cg2fib0fib1genFib1fib2genFib2sgcd sgcdIsCorrect genGCDInC popCountSlow popCountFastpop8fastPopCountIsCorrectgenPopCountInC shiftLeft tstShiftLeftgenCCodeKSKeyGF28gf28Multgf28Pow gf28InverserotRroundConstants invMixColumns keyExpansion sboxTablesbox unSBoxTableunSBoxsboxInverseCorrect addRoundKeyt0Funct0t1t2t3u0Funcu0u1u2u3doRoundsaesRound aesInvRoundaesKeySchedule aesEncrypt aesDecryptinvKeyExpansionaesInvKeyScheduleaesDecryptUnwoundKeycommonPT aes128Key aes192Key aes256Keyaes128CTaes192CTaes256CT aes128InvKey aes192InvKeyaes192InvKeyExtended aes256InvKeyextractFinalKeyextractFinalKeyExtendedt128Enct128Dect192Enct192Dect256Enct256Dec runAESTestsaes128IsCorrect aes128EnccgAES128BlockEncryptaesLibComponents cgAESLibrarycgAES128Libraryhex8chop4NibbleCTPTBlock expandKeyprop_ExpandKeyencryptdecryptprince princeCoreroundinvRoundmmInvsrsrInvprop_srm'matmMult nonLinearsBoxsBoxInv prop_SBox rConstantsprop_RoundKeys toNibbles fromNibbles testVectors showBlockRC4SinitSprgainitRC4 keySchedulekeyScheduleString rc4IsCorrecthex2SHA shaLoopCounth0 shaConstantssigma1Coefficientssigma0Coefficientssum1Coefficientssum0Coefficients blockSizewordSizechmajsum0sum1sigma0sigma1sha224Psha256Psha384Psha512P sha512_224P sha512_256PprepareMessage hashBlockshaPsha224sha256sha384sha512 sha512_224 sha512_256knownAnswerTestscgSHA256cgSHA512chunkByshowHashflyspeckSolution HomogeneousNonHomogeneousldnbasistestsailors$fShowSolutionEltSElt appendNullconsApp appendAssocreverseReverse $fSatModelElt $fHasKindElt $fSymValElt $fDataElt $fReadElt $fShowEltTtrueIsProvablefalseIsn'tProvablelargerIntegerExistsSTforallConjunctionexistsDisjunctionforallDisjunctionNotexistsConjunctionNot $fSatModelT $fHasKindT $fSymValT$fDataT$fReadT$fShowTz3NoAutoConfignotDiv3 sumConstProofsumProofsumSquareProofelevenMinusFourKleeneSKleenestar<= kleeneProofs$fSatModelKleene$fHasKindKleene$fSymValKleene $fDataKleene $fReadKleene $fShowKleenelistLengthProofbadProof lenAppend lenAppend2revLen badRevLensqrt2IsIrrationaltaoIdleReadyCriticalSStatesIdlesReady sCriticalmutex validSequence validTurns checkMutexnotFair$fSatModelState$fHasKindState $fSymValState $fDataState $fReadState $fShowState $fOrdState $fEqStateDeckcoatfourCoat coatCheckmkFibsgenFibsproblem allModelsmodelsWithYAuxadd1 add1ExamplesumToN sumToNExamplelen lenExamplepingPongevenOdd isEvenOddisEvenisOddevenOdd2ackack1yABSEsAsBsCeltsfourmaxEminE $fSatModelE $fHasKindE $fSymValE$fDataE$fReadE$fShowE$fOrdE$fEqEUVSU $fSatModelU $fHasKindU $fSymValU$fDataU$fReadU$fShowU $fSatModelV $fHasKindV $fSymValV$fDataV$fReadV$fShowVqe skolemEx1 skolemEx2 skolemEx3 skolemEx4 poExample tcExample1 tcExample2 tcExample3 assocPlusassocPlusRegularnonZeroAddition multInverse roundingAdd fp54Boundsmemset memsetExample outOfInitoutsidegenVals nestedArraySHumanHeightInCmHumanHeightInCmSMetresMetrestallestHumanEverceilingHighEnoughForHuman$fSymValMetres$fHasKindMetres$fSymValHumanHeightInCm$fHasKindHumanHeightInCm$fRealHumanHeightInCm$fIntegralHumanHeightInCm$fNumHumanHeightInCm$fEnumHumanHeightInCm$fEqHumanHeightInCm$fOrdHumanHeightInCm $fRealMetres$fIntegralMetres $fNumMetres $fEnumMetres $fEqMetres $fOrdMetres checkedDivtest1test2gfMultmultUnitmultComm multAssoc polyDivModtestGF28d1d2d3d4pathsSIexampleDictDayMonTueWedThuFriSunSDaysMonsTuesWedsThusFrisSatsSun isWeekend almostWeekendweekendJustOver firstWeekend $fMetricDay $fSatModelDay $fHasKindDay $fSymValDay $fDataDay $fReadDay $fShowDay$fOrdDay$fEqDay productionallocateInvquantifyvc1vc2vc3 synthesizeverifyyxex1ex2$fQueriableIOS $fEqSymbolicS$fShowS$fTraversableS $fFunctorS $fFoldableSnki fibCorrectpgm1pgm2ex3ex4ex5ex6s sumCorrectALUinputsenvRegImmregisterwzreadwriteinpaddmuldivmodeqlrunpuzzlemonad $fNumDataD14D15D16D17D18D19MonthMayJunJulAugSMonthsMaysJunsJulsAug$fSatModelMonth$fHasKindMonth $fSymValMonth $fDataMonth $fReadMonth $fShowMonth $fOrdMonth $fEqMonthBirthdayBDsD14sD15sD16sD17sD18sD19 mkBirthdayvalidcherylCoinmkCoin combinationsc1c2c3c4c5c6CountcountcountsActionInitialFillBig FillSmallEmptyBig EmptySmall BigToSmall SmallToBigCStateactionsmallbigSActionsInitialsFillBig sFillSmall sEmptyBig sEmptySmall sBigToSmall sSmallToBigdieHard$fQueriableIOState$fSatModelAction$fHasKindAction$fSymValAction $fDataAction $fReadAction $fShowAction $fOrdAction $fEqActionPSPddrinker $fSatModelP $fHasKindP $fSymValP$fDataP$fReadP$fShowPguesseseuler185 solveEuler185ColorRedGreenWhiteYellowBlue NationalityBritonDaneSwede NorwegianGermanSColorsRedsGreensWhitesYellowsBlue$fSatModelColor$fHasKindColor $fSymValColor $fDataColor $fReadColor $fShowColor $fOrdColor $fEqColorBeverageTeaCoffeeMilkBeerWater SNationalitysBritonsDanesSwede sNorwegiansGerman$fSatModelNationality$fHasKindNationality$fSymValNationality$fDataNationality$fReadNationality$fShowNationality$fOrdNationality$fEqNationalityPetDogHorseCatBirdFish SBeveragesTeasCoffeesMilksBeersWater$fSatModelBeverage$fHasKindBeverage$fSymValBeverage$fDataBeverage$fReadBeverage$fShowBeverage $fOrdBeverage $fEqBeverageSportFootballBaseball VolleyballHockeyTennisSPetsDogsHorsesCatsBirdsFish $fSatModelPet $fHasKindPet $fSymValPet $fDataPet $fReadPet $fShowPet$fOrdPet$fEqPetSSport sFootball sBaseball sVolleyballsHockeysTennis fishOwner$fSatModelSport$fHasKindSport $fSymValSport $fDataSport $fReadSport $fShowSport $fOrdSport $fEqSportFlowercol validPick flowerCountBlackGridSButtonButtonsBlacknextsearchJugcontentcapacitytransferinitJugssolvedmoves $fGenericJug$fMergeableJug InhabitantIdentityKnaveKnight SInhabitant$fSatModelInhabitant$fHasKindInhabitant$fSymValInhabitant$fDataInhabitant$fReadInhabitant$fShowInhabitant StatementTruthFalsity SIdentitysKnavesKnight$fSatModelIdentity$fHasKindIdentity$fSymValIdentity$fDataIdentity$fReadIdentity$fShowIdentity $fOrdIdentity $fEqIdentity SStatementsTruthsFalsityjohnbillissaysholdsandnotiff$fSatModelStatement$fHasKindStatement$fSymValStatement$fDataStatement$fReadStatement$fShowStatement$fOrdStatement $fEqStatement ladyAndTigersBoardRowElemcheckdiagisMagicchunkmagicRoleVictimKiller BystanderSexMaleFemaleBarBeachAlone SLocationsBarsBeachsAlone$fSatModelLocation$fHasKindLocation$fSymValLocation$fDataLocation$fReadLocation$fShowLocationSSexsMalesFemale $fSatModelSex $fHasKindSex $fSymValSex $fDataSex $fReadSex $fShowSex$fOrdSex$fEqSexConstgetConstPersonrolesexlocationagenmSRolesVictimsKiller sBystander newPerson getPersonkiller $fShowPerson$fSatModelRole $fHasKindRole $fSymValRole $fDataRole $fReadRole $fShowRole $fOrdRole$fEqRoleisValidnQueens solvePuzzleAmbalatBasahanKendisiTarakanHandlerDollyEvaFrancineGracie OrangutanMerahOfalloQuirrelShamir$fEnumOrangutan$fBoundedOrangutan SOrangutansMerahsOfallosQuirrelsShamir$fSatModelOrangutan$fHasKindOrangutan$fSymValOrangutan$fDataOrangutan$fReadOrangutan$fShowOrangutan$fOrdOrangutan $fEqOrangutanSHandlersDollysEva sFrancinesGracie$fSatModelHandler$fHasKindHandler$fSymValHandler $fDataHandler $fReadHandler $fShowHandler $fOrdHandler $fEqHandler Assignment MkAssignmenthandler orangutansAmbalatsBasahansKendisisTarakanmkSym$fGenericAssignment$fMergeableAssignmentRabbitSRabbitgreedyblackoldrabbits rabbitsAreOK$fSatModelRabbit$fHasKindRabbit$fSymValRabbit $fDataRabbit $fReadRabbit $fShowRabbit sendMoreMoneyPuzzle fillBoardsudokupuzzle1puzzle2puzzle3puzzle4puzzle5puzzle6 allPuzzlesProblem symProblemvisibletowerU2MemberBonoEdgeAdamLarryHereThereSTimeTime SU2MembersBonosEdgesAdamsLarry crossTime sCrossTime$fSatModelU2Member$fHasKindU2Member$fSymValU2Member$fDataU2Member$fReadU2Member$fShowU2Member $fOrdU2Member $fEqU2MemberActionsMovelLarrylAdamlEdgelBonoflashtimesHeresTherestartwhereIs xferFlash xferPerson bumpTime1 bumpTime2whenSmove1move2solveNsolveU2$fMergeableStateT$fGenericStatus$fMergeableStatusgoodSumdemocsDemo1csDemo2sharedqueryOnequeryTwosharedDependent firstQuery secondQuery demoDependentMondayTuesday WednesdayThursdayFridaySaturdaySundaysMondaysTuesday sWednesday sThursdaysFriday sSaturdaysSundayfindDaysBinOpDivideExptUnOpNegateSqrt FactorialSBinOpsPlussMinussTimessDividesExpt$fSatModelBinOp$fHasKindBinOp $fSymValBinOp $fDataBinOp $fReadBinOp $fShowBinOp $fOrdBinOp $fEqBinOpFSUnOpsNegatesSqrt sFactorialallPossibleTreesfillsCaseevalgeneratefind$fSatModelUnOp $fHasKindUnOp $fSymValUnOp $fDataUnOp $fReadUnOp $fShowUnOp $fOrdUnOp$fEqUnOpguessplayexampleMathSATpucCoresolveCrosswordMSQLExprConcatReadVarexampleProgramnameRestrReselectRedropRe statementRe exploitRe findInjection$fIsStringSQLExprQrunQ CheckResultProvedCounterexamplePropertyEvalunEvalTermVarLitEqualsEnvresultenvYenvXAllocrunAllocallocallocEnv unsafeCastSBVrunEvalmkResultrunProgramEvalrunPropertyEval generalizemkQuery $fFunctorQ$fApplicativeQ$fMonadQ $fMonadIOQ$fMonadErrorListQ $fMonadQueryQ$fEqCheckResult$fShowCheckResult $fFunctorEval$fApplicativeEval $fMonadEval$fMonadReaderEnvEval$fMonadErrorListEval$fEqEnv $fShowEnv$fFunctorAlloc$fApplicativeAlloc $fMonadAlloc$fMonadIOAlloc$fMonadErrorListAlloc$fMonadSymbolicAllocfthmSBor $fSatModelB $fHasKindB $fSymValB$fDataB$fReadB$fShowBthmGoodmul22 synthMul22BinaryTernaryposnegshannonshannon2 derivativenoWiggleunivOK existentialexistsOKSQ $fSatModelQ $fHasKindQ $fSymValQ$fDataQ$fReadQ$fShowQLSLclassifygenLs $fSatModelL $fHasKindL $fSymValL$fDataL$fReadL$fShowLAppSzstsysxs algorithmimperativeAppend$fQueriableIOAppS $fShowAppS $fGenericAppS$fMergeableAppS$fTraversableAppS $fFunctorAppS$fFoldableAppSIIncSprepostnoChange imperativeInc$fQueriableIOIncS $fShowIncS $fShowIncS0 $fGenericIncS$fMergeableIncS$fTraversableIncS $fFunctorIncS$fFoldableIncSFibSfib axiomatizeFib imperativeFib$fQueriableIOFibS $fShowFibS $fShowFibS0 $fGenericFibS$fMergeableFibS$fTraversableFibS $fFunctorFibS$fFoldableFibSGCDSjgcd axiomatizeGCD imperativeGCD$fQueriableIOGCDS $fShowGCDS $fShowGCDS0 $fGenericGCDS$fMergeableGCDS$fTraversableGCDS $fFunctorGCDS$fFoldableGCDSDDivSrq imperativeDiv invariantmeasure$fQueriableIODivS $fShowDivS $fShowDivS0 $fGenericDivS$fMergeableDivS$fTraversableDivS $fFunctorDivS$fFoldableDivSSqrtSsqrtimperativeSqrt$fQueriableIOSqrtS $fShowSqrtS $fShowSqrtS0$fGenericSqrtS$fMergeableSqrtS$fTraversableSqrtS$fFunctorSqrtS$fFoldableSqrtSLenSlimperativeLength$fQueriableIOLenS $fShowLenS $fGenericLenS$fMergeableLenSSumS imperativeSum$fQueriableIOSumS $fShowSumS $fShowSumS0 $fGenericSumS$fMergeableSumS$fTraversableSumS $fFunctorSumS$fFoldableSumSisStartModeOptionghc-prim GHC.TypesTrueisOnlyOnceOption setSMTOption$fShowSMTReasonUnknown$fNFDataSMTReasonUnknownisExactRational mkPolyRealalgRealStructuralEqualalgRealStructuralComparealgRealToSMTLib2algRealToHaskell ghc-internalGHC.Internal.RealRationalGHC.Internal.Data.EitherLeftRight mergeAlgReals$fFractionalAlgRealIO$fExtractIOWriterT$fExtractIOWriterT0$fExtractIOExceptTtransformers-0.6.1.1-1df5Control.Monad.Trans.ExceptExceptT$fExtractIOMaybeTControl.Monad.Trans.MaybeMaybeT $fExtractIOIO isKStringmlift2mlift3mlift4mlift5mlift6mlift7mlift8joinArgs splitArgs qfsToString stringToQFScheckObservableName InvalidFloat BVZeroWidth showBaseKind kindParensmtType kindHasSignconstructUKind intOfProxyeqCheckIsObjectEqhasUninterpretedSortsneedsFlattening $fShowKind$fHasKindProxy$fHasKindRoundingModeFloatGHC.Internal.WordWord32DoubleWord64bfRemoveRedundantExp bfToStringmkBFOpts fprToSMTLib2arbFPIsEqualObjectHarbFPCompareObjectHbfSignumGHC.Internal.Float encodeFloatlift1 $fRealFracFP$fRealFP $fRealFloatFP $fFloatingFP$fFractionalFP$fNumFP$fNumFloatingPoint$fShowFloatingPointeqRCSet compareRCSet GHC.ClassesOrdcvRank showExtCVshowCV randomCValrandomCV $fShowRCSet$fHasKindArrayModel $fOrdCValEq$fEqCVal$fShowCV $fHasKindCV $fShowExtCV$fHasKindExtCV$fShowGeneralizedCV$fHasKindGeneralizedCVtime-1.12.2-d1da(Data.Time.Clock.Internal.NominalDiffTimeNominalDiffTime SMTEnginepathCondSMTDef LambdaInputsInputsAllInps InternInps UserInputsIncStateCacheCgMapUIMapTableMapKindSetCnstMapExprMapProgInfo ResultInpGHC.Internal.MaybeNothingNROp SBVContextglobalSBVContext genSBVContext contextOfSVswKindswNodeIdregExpToSMTStringregExpToStringreorder showOpInfix toNamedSV' toNamedSV namedNodeIdgetSV getUserName getUserName' objectiveNameisSafetyCheckingIStage isSetupIStage isRunIStage newIncStatewithNewIncState onUserInputsonInternInputs onAllInputsaddInternInput addUserInput lookupInput getRootStategetSValPathConditionextendSValPathCondition noInteractivenoInteractiveEver modifyStatemodifyIncStaterecordObservableincrementInternalCounter addAssertionquantVar lambdaVarnewSV registerLabelnewConstcheckConsistentcompatibleContextcheckCompatibleContext mapSymbolicTsvMkTrackerVar svMkSymVarGenintroduceUserNamecontextMismatchErrorrunSymbolicInState uncacheGen mustIgnoreVarvalidationRequested$fOrdSV$fEqSV $fShowNROp $fShowOvOp $fShowRegExp $fNumRegExpGHC.Internal.NumNum$fIsStringRegExp $fShowRegExOp $fShowStrOp $fShowSeqOp$fShowQuantifier$fEqNamedSymVar$fMonoidInputs$fSemigroupInputs$fNFDataSMTDef $fShowSMTDef$fShowQueryContext$fShowSMTConfig$fEqSVal==/=$fMonadSymbolicSymbolicTSMTLamsmtDefGivenNamesvUninterpretedNamedArgs rNewAsgnsrNewConstraints rNewConstsrNewInps rNewKindsrNewTblsrNewUIs allInputs internInputs userInputsNR_ACosNR_ASinNR_ATanNR_CosNR_CoshNR_ExpNR_LogNR_PowNR_SinNR_SinhNR_SqrtNR_TanNR_Tanh hasQuantsprogSpecialRelsprogTransClosures ResultLamInps ResultTopInps SetComplement SetDelete SetDifferenceSetEqual SetInsert SetIntersect SetMember SetSubsetSetUnion IsLinearOrderIsPartialOrderIsPiecewiseLinearOrder IsTreeOrder parentStaterAssertsrCInforCgMap rConstraintsrDefns rIncState rLambdaLevel rObservables rOptGoalsrOutstandingAssertsrPartitionVars rProgInfo rQueryState rSMTOptionsrSVCacherUIMap rUsedKinds rUsedLbls rUserFuncs rconstMaprctrrexprMaprinps rlambdaInpsroutsrtblMaprunMode sbvContextspgmstCfg startTimesvStringsvCharsvSignum svDivides svImpliesrotsvShiftsvRotate svMkOverflow1 mkSymOpSCmkSymOpisConcreteZero isConcreteOneisConcreteOnes ghc-bignumGHC.Num.IntegerIntegerGHC.Internal.BitstestBit isConcreteMax isConcreteMin rationalCheck nonzeroCheckrationalSBVChecktupleLTmaybeLTeitherLTsvFloatAsSWord32svDoubleAsSWord64 svMkOverflow2$fArbitraryWordN$fIntegralWordNIntegral $fRealWordNReal $fEnumWordNGHC.Internal.EnumEnum $fNumWordN$fBoundedWordNBounded$fHasKindWordN $fShowWordN$fArbitraryIntN$fIntegralIntN $fRealIntN $fEnumIntN $fNumIntN $fBoundedIntN $fHasKindIntN $fShowIntN GEqSymbolicMaybeEitherFalseBoolGHC.Internal.Data.FoldablemkQArgsymbolicEqDefaultrewriteExistsUnique$fEqSBV $fShowSBVGHC.Internal.ShowShow$fQuantifiedBoolSBV $fLambdamSBV$fConstraintmSBV $fLambdamFUN$fConstraintmFUN$fConstraintmFUN0$fConstraintmFUN1$fConstraintmFUN2$fSymValRoundingMode $fIsListSBV$fConstraintmFUN3$fSkolemizeFUN$fSkolemizeFUN0$fSkolemizeFUN1$fSkolemizeFUN2$fSkolemizeFUN3$fSkolemizeSBV $fQNotFUN $fQNotFUN0 $fQNotFUN1 $fQNotFUN2 $fQNotFUN3 $fQNotSBVSExprtokenize parenDeficit parseSExprrdFPgetTripleFloatgetTripleDouble constantMapparseSExprFunctionparseSetLambdaparseLambdaExpressionparseStoreAssociations chainAssignsmakeHaskellFunctionEAppEConEDoubleEFloatEFloatingPointENumERealpads2s16showSMTRationaltoSMTLibRational HasFloatData FloatDataFPKindCrackNumintgetKindgetExponentDatafloatmkRuler $fCrackNumCV $fShowFPKind$fHasFloatDataFP$fHasFloatDataDouble$fHasFloatDataFloatSMTLibIncConverterSMTLibConverteraddAnnotationsshowTimeoutValuealignDiagnostic alignPlainalignWithPrefixdebug mergeSExpr$fShowSBVException$fExceptionSBVExceptioncvtdeclSort declTuplefindTupleArities containsSum containsMaybecontainsRationalscvtIncconstructTablescvtCVcvtExp declUserFunstoSMTLib toIncSMTLib toSMTLib2 toIncSMTLib2 SolverLine SolverRegular SolverTimeoutSolverException resultConfig getPrecision parseModelOutInt showSMTResultshowModelDictionary showModelUIshCV pipeProcessstandardEnginestandardSolver runSolver recordEndTimestartTranscriptfinalizeTranscript$fSatModelTuple7$fSatModelTuple6$fSatModelTuple5$fSatModelTuple4$fSatModelTuple3$fSatModelTuple2$fSatModelList$fSatModelCharChar$fSatModelList0GHC.Internal.BaseString$fSatModelRoundingMode $fSatModelCV$fSatModelIntN$fSatModelWordN$fSatModelFloatingPoint$fSatModelDouble$fSatModelFloat$fSatModelAlgReal$fSatModelInteger$fSatModelInt64GHC.Internal.IntInt64$fSatModelWord64$fSatModelInt32Int32$fSatModelWord32$fSatModelInt16Int16$fSatModelWord16Word16$fSatModelInt8Int8$fSatModelWord8Word8$fSatModelBool$fSatModelUnit$fModelableSMTResult$fModelableSatResult$fModelableThmResult inSubState lambdaGennamedLambdaGen constraintGenconverttoLambda$fQuantifiedBoola SMTFunctionaddQueryConstraint getConfig getObjectives getSBVPgmgetSBVAssertions syncUpSolver getQueryState trackAsserts askIgnoringpointWiseExtractmkSaturatingArggetValueCVHelperdefaultKindedValue sexprToValrecoverKindedValue extractValuegetTopLevelInputsgetAllSatResultparse runProofOn$fSolverContextQueryT$fSMTFunctionFUNTuple8r$fSMTFunctionFUNTuple7r$fSMTFunctionFUNTuple6r$fSMTFunctionFUNTuple5r$fSMTFunctionFUNTuple4r$fSMTFunctionFUNTuple3r$fSMTFunctionFUNTuple2r$fSMTFunctionFUNTuple8r0$fSMTFunctionFUNTuple7r0$fSMTFunctionFUNTuple6r0$fSMTFunctionFUNTuple5r0$fSMTFunctionFUNTuple4r0$fSMTFunctionFUNTuple3r0$fSMTFunctionFUNTuple2r0$fSMTFunctionFUNar sexprToArg sexprToFun smtFunDefault smtFunNamesmtFunSaturate smtFunType classifyModelgetModelAtIndexgetObjectiveValuescheckSatAssumingHelperrestoreTablesAndArraysgetUnsatCoreIfRequested allOnStdOutvalidatedefs2smtgenerateSMTBenchMarkGenmkArg runWithQuery runInThread sbvWithAny sbvWithAllfinishUIKindUIFreeUIFunUICodeC GMergeablesymbolicMergeDefaultquotRemdivModquotpopCountsetBitclearBitOrderingmaxmingenVargenVar_liftPB pbToIntegerlift1Flift1FNSlift2FNS lift1SReal lift2SReal fromIntegral liftViaSValshiftLshiftRrotateLrotateRenumCvtsymbolicMergeWithKind cannotMerge concreteMergeslet$fSolverContextSymbolicT $fBitsSBV $fFloatingSBV$fFloatingSBV0$fFloatingSBV1$fEqSymbolicRegExp$fSymValTuple8$fSymValTuple7$fSymValTuple6$fSymValTuple5$fSymValTuple4$fSymValTuple3$fSymValTuple2 $fSymValUnit $fSymValIntN $fSymValWordN$fSDivisibleSBV$fSDivisibleSBV0$fSDivisibleIntN$fSDivisibleWordN$fOrdSymbolicSBV $fMetricIntN $fMetricWordNTupleHasFieldsymbolicFieldAccesssppolyMultsvAllallZeroallOnelift2lift3 concEval1 concEval2 concEval3isConcretelyEmptyJustgenericFromFloatgenericToFloat concEval2BaddRMlift1BliftMMlift2Blift1FPlift2FPlift3FP$fRealFloatFloatingPoint$fRealFracFloatingPoint$fRealFloatingPoint$fMetricDouble $fMetricFloat$fIEEEFloatingDouble$fIEEEFloatingFloat liftFunL1 liftPredL1__unuseddeclareSymbolicensureEnumerationensureEmptyDatarender' pprCFunHeaderdeclSV declSVNoConstshowSVpprCWord showCType specifiermkConstgenMake genHeader genDrivergenCProg mergeToLib genLibMake mergeDrivers ToSizedBV ToSizedCstr FromSizedBV FromSizedCstr ToSizedErr FromSizedErrbase Data.RatioapproxRational bitDefaultpopCountDefaulttestBitDefaulttoIntegralSizedGHC.Internal.Data.Bits!<<.!>>..<<..>>..^.oneBits% denominator numerator bitReverse16 bitReverse32 bitReverse64 bitReverse8 byteSwap16 byteSwap32 byteSwap64.&..|.bitbitSize bitSizeMaybe complementBitisSignedrotateshift unsafeShiftL unsafeShiftRxorzeroBits FiniteBitscountLeadingZeroscountTrailingZeros finiteBitSizegetAndIffgetIffIorgetIorXorgetXorRatioWordsanitizeRelNamecheckSpecialRelationLocisTotaldispVCisClosed proofName isUserAxiom rootOfTrust RootOfTrustSelfProp internalAxiomlemmaGen $fShowProof$fInductionFUN$fInductionFUN0$fInductionFUN1$fInductionFUN2$fInductionFUN3$fInductionFUN4$fInductionFUN5$fInductionFUN6 ChainLemma makeStepslcasebparabinsertminMaxBVBMCKindbmcWithGHC.Internal.Generics"GHC.Internal.Data.Functor.Identity