Is there an UnsignedIntSort in Z3? - z3

I am using functions in my solver to model discrete time. The problem is that right now we use functions like z3.Function('f', IntSort(), IntSort()) and negative input values to the functions is really not applicable here because time starts at t=0. This causes problems when I want to proove things because the solver finds negative time solutions that should not be considered at all.
So my question is: Is there some kind of unsigned int sort (UnsignedIntSort) in z3?

As pointed out in the comments, there's no such sort; and your best bet is to make sure you have t >= 0 assertions for all uses.
Note that this is actually trickier in practice. Not only you need to make this assertion for all your "fresh" variables, but also whenever you do any arithmetic with such variables to ensure the results remain within the domain. That is, if you ever compute t-1, then you'll want t >= 1 as an assertion appearing, assuming the result of that expression is used as a time value itself.
This can get really tedious really quick, so having a mechanism ("overloaded arithmetic") can simplify life. But of course, that depends on exactly how you are programming your constraints, whether you're using SMT-Lib, or one of the APIs via a higher-level language.

There is no unsigned sort in SMT or Z3, because bit-vectors can trivially be used for this purpose. Bit-vectors hemselves are neither unsigned nor signed, but they are strings of bits. Signed and unsigned semantics are then implemented in separate functions, i.e., there is no generic less-than operator for bit-vectors, but there are bvult and bvslt for unsigned and signed less-than. Thus, as long as you stick to the unsigned flavours of all BV functions, you will always preserve unsigned semantics.
Also, in models, bit-vectors are usually provided as bit-strings (in binary or hex), i.e., there are no negative values. Insofar, in your application, you can always assume all bit-vectors are unsigned until you start using the *s* functions.

Related

Performance issues with z3py using modulo and optimization

I'm experimenting with Z3 (using the python api) where I'm building up a scheduling model for a class assignment, where I have to use modulo quite often (because its periodic). Modulo seems already to slow down z3 by a lot, but if I try do some optimization on top (minimize a cost function which is a sum), then it takes quite some time for fairly small problems.
Without optimization it works okayish (few seconds for a smaller problem). So that being said, I have now 2 questions:
1) Is there any trick with the modulo function of how to use it? I already assign the modulo value to a function. Or is there any other way to express periodic/ring behavior?
2) I am not interested in finding THE best solution. A good one, will be good enough. Is there a way to set some bounds for the cost function. Like, if know the upper and lower bound of it? Any other tricks, where I could use domain knowledge to find solutions fast.
Furthermore, I thought that if I ll use timeout option solver.set("timeout" 10000), then the solver would time out with the best solution so far. That doesnt seem to be the case. It just times out.
Impossible to comment on the mod function without seeing some code. But as a rule of thumb, division is difficult. Are you using Int values, or bit-vectors? If you are using unbounded integers, you might want to try bit-vectors which might benefit from better internal heuristics. Or try Real values, and then do a proper reduction.
Regarding how to get the "best so far" optimal value, see this answer: Finding suboptimal solution (best solution so far) with Z3 command line tool and timeout
Instead of using the built-in modulo and division, you could introduce uninterpreted functions mymod and mydiv, for which you only provide the necessary axioms of division and modulo that your problem requires. If I remember correctly, Microsoft's Ironclad and/or Ironfleet team did that when they had modulo/division-related performance problems (using the pipeline Dafny -> Boogie -> Z3).

How can I represent integer infinity in Z3?

I need to be able to compare two integer expressions, which may include literal integers, addition, unary negation, integer constants, and infinity, and decide if an inequality between them is satisfiable. This is part of a larger program, so there is no way for me to know ahead of time what those expressions will look like.
I have considered defining an integer constant and just letting it take any value, but then I realized that Infinity < 5 would be satisfiable.
I have considered defining a constant and making a universally quantified assertion that it is greater than all integers, but I don't know what Sort I should say it is. If I tell Z3 that the Sort of my Infinity constant is integer, I think it will probably happily go off and try to find me THE LARGEST INTEGER! I'm pretty sure that won't end the way I want.
I would create a composite type consisting of an integer and a boolean that says whether this particular value is infinity or not. Then, you need to define arithmetic on this. For example, if one of the operands is infinity then the result of an addition is infinity as well. Otherwise, it's the actual sum of the integers. Comparisons would be defined in a similar way (case based).
There is no need to actually create a type in the Z3 system. Just always create values in int/bool pairs in your code. A few helper functions can do that.
Doing this you will probably create a harder problem for Z3 to solve and maybe even escalate the logic you are using.

Lua floating point operations

I run Lua on a CPU without dedicated floating point HW, depending on SW emulation.
From luaopt.h I can see that some macros are set to double, but it does not clearly state when floats are used and its a little hard to track it.
If my script does simple stuff like:
a=0
a=a+1
for...
Would that involve a floating point operations at any level?
If no that's fine, but what is then the benefit to change macros to long?
(I tried of course but did not work....)
All numeric operations in Lua are performed (according to the default configuration) in floating point. There is no distinction made between floating point and integer, all values are simply numbers.
The actual C type used to store a Lua number is set in luaconf.h, and it is both allowed and even practical to change that to a suitable integral type. You start by changing LUA_NUMBER from double to int, long, or perhaps ptrdiff_t. Then you will find you need to tweak the related macros that control the conversions between strings and numbers. And, of course, you will likely need to eliminate most or all of the base math library since math.sin() and its friends and neighbors are not particularly useful over integers.
The result will be a Lua interpreter where all numbers are integers. The language will still allow you to type 3.14, but it will be stored as 3. Your code will likely not be completely portable to a Lua interpreter built with the standard configuration since a huge amount of Lua code casually assumes that floating point arithmetic is permitted, and remember that your compiled byte code will definitely not be compatible since byte code will store numbers as LUA_NUMBER.
There is LNUM patch (used, for example, by OpenWrt project which relies heavily on Lua for providing Web UI on hardware without FPU) that allows dual integer/floating point representation of numbers in Lua with conversions happening behind the scenes when required. With it most integer computations will be performed without resorting to FPU. Unfortunately, it's only applicable to Lua 5.1; 5.2 is not supported.

Why do Delphi and Free Pascal usually prefer a signed-integer data type to unsigned one?

I'm not a Pascal newbie, but I still don't know until now why Delphi and Free Pascal usually declares parameters and returned values as signed integers whereas I see them should always be positive. For example:
Pos() returns type of Integer. Is it possible to be a negative?
SetLength() declares the NewLength parameter as a type of Integer. Is there a negative length for string?
System.THandle declared as Longint. Is there a negative number for handles?
There are many decisions like those in Delphi and Free Pascal. What considerations were behind this?
In Pascal, Integer (signed) is the base type. All other integer number types are a subranges of integer. (this is not entirely true in Borland dialects, given longint in TP and int64 in Delphi, but close enough).
An important reason for that if the intermediate result of calculations gets negative, and you calculate with unsigned integers, range check errors will trigger, and since most older programming languages DON'T assume 2-complement integers, the result (with range checks off) might even be corrupt.
The THandle case is much simpler. Delphi didn't have a proper 32-bit unsigned till D4, but only a 31-bit cardinal. (since 32-bit unsigned integer is not a subrange of integer, the later unsigned ints are a subset of int64, which moved the problem to uint64 which was only added in D2010 or so)
So in many places in the headers signed types are used where the winapi uses unsigned types, probably to avoid the 32th bit getting accidentally corrupt in those versions, and the custom stuck.
But the winapi case is different from the general case.
Added later Some Pascal (and Modula2/3) implementations circumvent this trap by setting the integer at a size larger than the wordsize, and require all numeric types to declare a proper subrange, like in the below program.
The first holds the primary assumption that everything is a subset of integer, and the second allows the compiler to scale nearly everything down again to fit in registers, specially if the CPU has some operations for larger than word operations. (like x86 where 32-bit * 32-bit mul gives a 64-bit result, or can detect wordsize overflows using status bits (e.g. to generate range exceptions for adds without doing a full 2*wordsize add)
var x : 0..20;
y : -10..10;
begin
// any expression of x and y has a range -10..20
Turbo Pascal and Delphi emulate an integer type twice the wordsize for their 16-bit and 32-bit offerings. The handling of the highest unsigned type is hacky at best.
Well, for a start THandle is declared incorrectly. It's unsigned in the Windows headers and should be so in Delphi. In fact I think this was corrected in a recent release of Delphi.
I'd imagine that the preference for signed over unsigned is largely historical and not particularly significant. However, I can think of one example where it is important. Consider the for loop:
for i := 0 to Count-1 do
If i is unsigned and Count is 0 then this loop runs from 0 to $FFFFFFFF which is not what you want. Using a signed integer loop variable avoids that problem.
Pascal is a victim of its syntax here. The equivalent C or C++ loop has no such trouble
for (unsigned int i=0; i<Count; i++)
due to the syntactic difference and use of a comparison operator as stopping condition.
This could also be the reason why Length() on a string or dynamic array returns a signed value. And so for consistency, SetLength() should accept signed values. And given that the return value of Pos() is used to index strings, it should be signed also.
Here's another Stack Overflow discussion of the topic: Should I use unsigned integers for counting members?
Of course, I'm speculating wildly here. Perhaps there was no design and just out of habit the precedent of using signed values was set and became enshrined.
Some string related search functions return -1 when nothing is found.
I believe the reasoning behind this is that MaxInt is 2GB which is the maximum size for strings in 32 bit Delphi. This because a single process can have up to 2GB memory
There are many reasons for using signed integers, even some that might apply when you do not intend to return a negative value.
Imagine I write code that calls Pos, and I want to do math with the results. Would you rather have a negative result (Pos('x',s)-5) raise a range-check exception, underflow and become a very large unsigned number around 4 billion, or go negative, if Pos('x',s) returns 1? Either one is a source of problems for new users who seldom think about these cases, but the long-established tradition is that by using Integer results, it's your job to check for negative and zero results and not use them as string offsets. There is an advantage for beginning and for advanced programmers, in using Integer, and not having "negative" values roll under and become large unsigned values or raise range exceptions.
Secondly, remember that in beginning programming, one usually introduces Integer (signed) types long before one introduces unsigned types like Cardinal. Beginners often work with functions like Pos, and it makes sense to use the type that will create the least-unfriendly set of side effects. There are no negative side effects to having a range larger than the one you absolutely need (the range you probably need for Pos is 1 to maximum-string-length-in-delphi). There is zero benefit in 32-bit Delphi to using the Cardinal type for Pos, and there definitely ARE downsides to choosing it.
Once you get to 64-bit delphi, however, you could theoretically have strings LARGER than an Integer can hold, and moving to Cardinal wouldn't fix all your potential problems. However, the chance of anyone having a 2+ GB string is probably nil, and Delphi 64-bit compiler doesn't allow a >2 GB string, anyway. In my testing, I can achieve an almost 1 GB String in 64 bit Delphi. So the practical length limit for a Win64 string is about a billion (1073741814) characters, which is using nearly 2 GB of actual RAM. At that limit, I either get EIntOverflow or EAccessViolation, and it seems I am hitting Delphi run time library (RTL) bugs, not properly defined limits, so your mileage may vary.

Should I use unsigned integers for counting members?

Should I use unsigned integers for my count class members?
Answer
For example, assume a class
TList <T> = class
private
FCount : Cardinal;
public
property Count : Cardinal read FCount;
end;
That does make sense, doesn't it? The number of items stored in a list can't be negative, so why not use an unsigned integer type for it? I think it's in general a good principle to always use the least general (ergo the most special) type possible.
Now, iterating over a list looks like this:
for I := 0 to List.Count - 1 do
Writeln (List [I]);
When the number of items stored in the list is zero, the compiler tries to evaluate
List.Count - 1
which results in a nice Integer overflow (underflow to be exact). Combined with the fact that the debugger does not show the appropriate location where the exception occured, this was very hard to find for me.
Let me add that if you have overflow checking turned off, the resulting errors will be even harder to track, because then you will often access memory that doesn't belong to you - and that results in undefined behaviour.
I will be using plain Integers for all my count members from now on to avoid situations like this.
If that's complete nonsense, please point it out to me :)
(I just spent an hour tracking an integer overflow in my code, so I decided to share that - most people on here will know that of course, but perhaps I can save someone some time.)
No, definitely not. Delphi idiom is to use integers here. Don't fight the language.
In a 32 bit environment you'll not have more elements in the list, except if you try to build a bitmap.
Let's be clear: every programmer who is going to have to use your code is going to hate you for using a Cardinal instead of an integer.
Unsigned integers are almost always more trouble than they're worth because you usually end up mixing signed and unsigned integers in expressions at some point. That means that the type will need to be widened (and probably have a performance hit) to get correct semantics (ideally the compiler does this as per language definition), or else you'll need to be very careful in your range checking.
Take C/C++ for example: size_t is the type of the integer for memory sizes and allocation, and is unsigned, but ptrdiff_t is the type for the offset you get when you subtract one pointer from another, and necessarily is signed. Want to know how many elements you've allocated in an array? Perhaps you subtract the first element address from the last+1 element address and divide by sizeof(element-type)? Well, now you've just mixed signed and unsigned integers.
Regarding your statement that "I think it's in general a good principle to always use the least general (ergo the most special) type possible." - actually I think it's a good principle to use the data type that will cause you least angst and trouble.
Generally for me that's a signed int since:
I don't usually have lists with 231 or more elements in them.
You shouldn't have lists that big either :-)
I don't like the hassle of having special edge cases in my code.
But it's really a style issue. If 'purity' of code is more important to you than brevity of code, your method is best (with modifications to catch the edge cases). Myself, I prefer brevity since edge cases tend to clutter the code and reduce understanding.
Don't.
It's not just going against a programming idiom, it's an explicit request to the compiler to use unsigned arithmetic, that is either prone to anomalous behaviors (if you don't guard against overflows) or to irrelevant runtime exceptions (if you guard against overflows, a temporary overflow will be fatal, f.i when you subtract before adding, even if the final result is positive, and I'm referring to the CPU opcode-level ordering of operations, which may not bear a trivial relationship to what you have in your code).
Keep in mind "unsigned" does not translate to "positive", it translates to "doesn't have a sign", which is different. The term "unsigned" was picked for good reason (and naming it "Cardinal" in Delphi was a poor choice IMO).
Unsigned types are for raw storage specifications, bitwise operations, ASM code, embedded controllers and other specialty uses. When you're doing high-level programming, you should forget you ever heard about unsigned types.
Moral: use iterators and foreach when you can, because it avoids this question altogether.
Boundary conditions frequently present problems. Allowing for a type that can go negative may just shift the issue. Perhaps it shifts it in a way that's easier to debug, perhaps not. I started off using integers for counting loops like that, but later on switched to cardinals to help me catch errors.

Resources