How do I create additional constraints from a model obtained by a solver in z3 Python API? - z3

Once I have a constraint problem, I would like to see if it is satisfiable. Based on the returned model (when it is sat) I would like to add assertions and then run the solver again. However, it seems like I am misunderstanding some of the types/values contained in the returned model. Consider the following example:
solv = z3.Solver()
n = z3.Int("n")
solv.add(n >= 42)
solv.check() # This is satisfiable
model = solv.model()
for var in model:
# do something
solv.add(var == model[var])
solv.check() # This is unsat
I would expect that after the loop i essentially have the two constraints n >= 42 and n == 42, assuming of course that z3 produces the model n=42 in the first call. Despite this, in the second call check() returns unsat. What am I missing?
Sidenote: when replacing solv.add(var == model[var]) with solv.add(var >= model[var]) I get a z3.z3types.Z3Exception: Python value cannot be used as a Z3 integer. Why is that?

When you loop over a model, you do not get a variable that you can directly query. What you get is an internal representation, which can correspond to a constant, or it can correspond to something more complicated like a function or an array. Typically, you should query the model with the variables you have, i.e., with n. (As in model[n].)
You can fix your immediate problem like this:
for var in model:
solve.add(var() == model[var()])
but this'll only work assuming you have simple variables in the model, i.e., no uninterpreted-functions, arrays, or other objects. See this question for a detailed discussion: https://stackoverflow.com/a/11869410/936310
Similarly, your second expression throws an exception because while == is defined over arbitrary objects (though doing the wrong thing here), >= isn't. So, in a sense it's the "right" thing to do to throw an exception here. (That is, == should've thrown an exception as well.) Alas, the Python bindings are loosely typed, meaning it'll try to make sense of what you wrote, not necessarily always doing what you intended along the way.

Related

Floor and Ceiling Function implementation in Z3

I have tried to implement Floor and Ceiling Function as defined in the following link
https://math.stackexchange.com/questions/3619044/floor-or-ceiling-function-encoding-in-first-order-logic/3619320#3619320
But Z3 query returning counterexample.
Floor Function
_X=Real('_X')
_Y=Int('_Y')
_W=Int('_W')
_n=Int('_n')
_Floor=Function('_Floor',RealSort(),IntSort())
..
_s.add(_X>=0)
_s.add(_Y>=0)
_s.add(Implies(_Floor(_X)==_Y,And(Or(_Y==_X,_Y<_X),ForAll(_W,Implies(And(_W>=0,_W<_X),And(_W ==_Y,_W<_Y))))))
_s.add(Implies(And(Or(_Y==_X,_Y<_X),ForAll(_W,Implies(And(_W>=0,_W<_X),And(_W==_Y,_W<_Y))),_Floor(_X)==_Y))
_s.add(Not(_Floor(0.5)==0))
Expected Result - Unsat
Actual Result - Sat
Ceiling Function
_X=Real('_X')
_Y=Int('_Y')
_W=Int('_W')
_Ceiling=Function('_Ceiling',RealSort(),IntSort())
..
..
_s.add(_X>=0)
_s.add(_Y>=0)
_s.add(Implies(_Ceiling(_X)==_Y,And(Or(_Y==_X,_Y<_X),ForAll(_W,Implies(And(_W>=0,_W<_X),And(_W ==_Y,_Y<_W))))))
_s.add(Implies(And(Or(_Y==_X,_Y<_X),ForAll(_W,Implies(And(_W>=0,_W<_X),And(_W==_Y,_Y<_W)))),_Ceiling(_X)==_Y))
_s.add(Not(_Ceilng(0.5)==1))
Expected Result - Unsat
Actual Result - Sat
[Your encoding doesn't load to z3, it gives a syntax error even after eliminating the '..', as your call to Implies needs an extra argument. But I'll ignore all that.]
The short answer is, you can't really do this sort of thing in an SMT-Solver. If you could, then you can solve arbitrary Diophantine equations. Simply cast it in terms of Reals, solve it (there is a decision procedure for Reals), and then add the extra constraint that the result is an integer by saying Floor(solution) = solution. So, by this argument, you can see that modeling such functions will be beyond the capabilities of an SMT solver.
See this answer for details: Get fractional part of real in QF_UFNRA
Having said that, this does not mean you cannot code this up in Z3. It just means that it will be more or less useless. Here's how I would go about it:
from z3 import *
s = Solver()
Floor = Function('Floor',RealSort(),IntSort())
r = Real('R')
f = Int('f')
s.add(ForAll([r, f], Implies(And(f <= r, r < f+1), Floor(r) == f)))
Now, if I do this:
s.add(Not(Floor(0.5) == 0))
print(s.check())
you'll get unsat, which is correct. If you do this instead:
s.add(Not(Floor(0.5) == 1))
print(s.check())
you'll see that z3 simply loops forever. To make this usefull, you'd want the following to work as well:
test = Real('test')
s.add(test == 2.4)
result = Int('result')
s.add(Floor(test) == result)
print(s.check())
but again, you'll see that z3 simply loops forever.
So, bottom line: Yes, you can model such constructs, and z3 will correctly answer the simplest of queries. But with anything interesting, it'll simply loop forever. (Essentially whenever you'd expect sat and most of the unsat scenarios unless they can be constant-folded away, I'd expect z3 to simply loop.) And there's a very good reason for that, as I mentioned: Such theories are just not decidable and fall well out of the range of what an SMT solver can do.
If you are interested in modeling such functions, your best bet is to use a more traditional theorem prover, like Isabelle, Coq, ACL2, HOL, HOL-Light, amongst others. They are much more suited for working on these sorts of problems. And also, give a read to Get fractional part of real in QF_UFNRA as it goes into some of the other details of how you can go about modeling such functions using non-linear real arithmetic.

F#: How to examine content in a n-tuple and return true or false?

Consider this F# code:
let isSalary employee =
let (fName,lName,Occupation,Department,SalaryType,
HoursPerWeek, AnnualSalary, HourlyWage
) = employee
SalaryType = "Salary"
if(employee.SalaryType = SalaryType) then
true
else
false
Im getting errors in here, any fixes to it?
First things first, please post error messages and a much more specific question. Thanks! But luckily, I can about deduce the error messages from this problem.
Next, if you want to mutate SalaryType after you've deconstructed your employee 8-tuple, you should write using the mutable keyword:
let mutable (fName, lName, Occupation, Department, SalaryType,
HoursPerWeek, AnnualSalary, HourlyWage) = employee
But you shouldn't. This is explained further below.
Next problem: there is no dot notation (no tuple.member) for accessing members of a tuple. It's only possible through deconstruction. So you can't employee.SalaryType.
Here's what looks to be the crux of the problem, and it's a mistake I made many times when I was learning functional programming, and it's a difficult paradigm shift to adapt to. You should not be attempting to mutate data, or in this case, variables. Variables, or values as they are called in F#, shouldn't change, as a broad rule. Functions should be pure.
What this means is that any parameters you pass into a function should not change after leaving the function. The parameter employee should be the same after you return to the calling scope.
There's a few syntactical errors you've made that make it pretty much impossible for me to deduce what you're trying to do in the first place. Please include this in the question.
Also, one last nitpick. As you know, the last expression in an F# function is it's return value. Instead of using an if statement, just return the condition you're testing, like this:
let ...
...
employee.SalaryType = SalaryType <- but remember, you can't use dot notation on tuples; this is just an example
Please read more on
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/

Creating variables, pairs, and sets in Z3Py

this is a three part question on the use of the Python API to Z3 (Z3Py).
I thought I knew the difference between a constant and a variable but apparently not. I was thinking I could declare a sort and instantiate a variable of that sort as follows:
Node, (a1,a2,a3) = EnumSort('Node', ['a1','a2','a3'])
n1 = Node('n1') # c.f. x = Int('x')
But python throws an exception saying that you can't "call Node". The only thing that seems to work is to declare n1 a constant
Node, (a1,a2,a3) = EnumSort('Node', ['a1','a2','a3'])
n1 = Const('n1',Node)
but I'm baffled at this since I would think that a1,a2,a3 are the constants. Perhaps n1 is a symbolic constant, but how would I declare an actual variable?
How to create a constant set? I tried starting with an empty set and adding to it but that doesn't work
Node, (a1,a2,a3) = EnumSort('Node', ['a1','a2','a3'])
n1 = Const('n1',Node)
nodes = EmptySet(Node)
SetAdd(nodes, a1) #<-- want to create a set {a1}
solve([IsMember(n1,nodes)])
But this doesn't work Z3 returns no solution. On the other hand replacing the 3rd line with
nodes = Const('nodes',SetSort(Node))
is now too permissive, allowing Z3 to interpret nodes as any set of nodes that's needed to satisfy the formula. How do I create just the set {a1}?
Is there an easy way to create pairs, other than having to go through the datatype declaration which seems a bit cumbersome? eg
Edge = Datatype('Edge')
Edge.declare('pr', ('fst', Node), ('snd',Node))
Edge.create()
edge1 = Edge.pr(a1,a2)
Declaring Enums
Const is the right way to declare as you found out. It's a bit misleading indeed, but it is actually how all symbolic variables are created. For instance, you can say:
a = Const('a', IntSort())
and that would be equivalent to saying
a = Int('a')
It's just that the latter looks nicer, but in fact it's merely a function z3 folks defined that sort of does what the former does. If you like that syntax, you can do the following:
NodeSort, (a1,a2,a3) = EnumSort('Node', ['a1','a2','a3'])
def Node(nm):
return Const(nm, NodeSort)
Now you can say:
n1 = Node ('n1')
which is what you intended I suppose.
Inserting to sets
You're on the right track; but keep in mind that the function SetAdd does not modify the set argument. It just creates a new one. So, simply give it a name and use it like this:
emptyNodes = EmptySet(Node)
myNodes = SetAdd(emptyNodes, a1)
solve([IsMember(n1,myNodes)])
Or, you can simply substitute:
mySet = SetAdd(SetAdd(EmptySet(Node), a1), a2)
which would create the set {a1, a2}.
As a rule of thumb, the API tries to be always functional, i.e., no destructive updates to existing variables, but you instead create new values out of old.
Working with pairs
That's the only way. But nothing is stopping you from defining your own functions to simplify this task, just like we did with the Node function in the first part. After all, z3py is essentially Python library and z3 folks did a lot of work to make it nicer, but you also have the entire power of Python to simplify your life. In fact, many other interfaces to z3 from other languages (Scala, Haskell, O'Caml etc.) precisely do that to provide a much easier to work with API using the features of their respective host languages.

Dafny verification - refer to original var in post condition

I am trying to verify my code in Dafny and I encountered a problem:
I have a method that is iterating over a sequence and changes it. The method changes the sequence according to the elements in the sequence. I would like to add a post condition like this: "if the elements in the sequence are X then something should happen". The problem is that the method changes the set (adds element etc.) and I want to check the condition of the original sequence. Is there an elegant way of doing that in Dafny? (The only way I could think of right now is keeping global var of the original condition of the sequence, but I am looking for the right way of doing that).
Code example:
method changeSeq(p: class1, s: seq<class1>)
ensures |s| == 10 ==> p in s
{
if (|s| == 10){
s := s + [p];
}
}
In the code, I want the post condition to check original s stat, and not its stat after we changed it.
you can use old for old value of a variable like s == old(s).
Here is one example: http://rise4fun.com/Dafny/fhQgD
From Dafny Documentation 22.18. Old Expressions
OldExpression_ = "old" "(" Expression(allowLemma: true, allowLambda: true) ")"
An old expression is used in postconditions. old(e) evaluates to the value expression e had on entry to the current method. Note that old only affects heap dereferences, like o.f and a[i]. In particular, old has no effect on the value returned for local variables or out-parameters.

Design disagreement: Security checks

We (two people) are doing a project using Lua as an embedded language.
My teammate uses argument type checks almost everywhere:
function someFunction( a, b,c )
if a == nil then return end
--Some stuff here
if type( b ) ~= "function" then
Error( "blah" )
end
--More here
if someTable[ c ] == nil then someTable[ c ] = {}
end
I don't really like that as I think that most of those checks are unneccessary.. it kind of takes the "spirit" of using Lua. It also makes the code longer, slower and less readable in my opinion.
In general I would do it this way:
function someFunction( a, b,c )
--More here
if someTable[ c ] == nil then someTable[ c ] = {}
end
I leave out almost all type/argument checks and only do those who have a high chance of actually happening.
Now we are unsure of what solution is better and decided to ask you: Security checks in Lua - yes or no?
I'm not familiar with Lua, but Wikipedia seems to think it is duck-typed. I'm going to draw an analogy with Python, so forgive me if it's not appropriate.
In Python, functions are designed with the principle that they need an object that meets certain criteria. If you pass in a different object than what the original author intended, as long as it meets the criteria of the function, it should work. The idea being, "if it looks like a duck, walks like a duck, and quacks like a duck, it is a duck." (Hence the name.) That said, there are a few rare instances where you need an object of a specific type, but this is not the general case.
At any rate, you appear to be "fighting the language", which is a code smell in my book. Most languages are designed and intended to be used in certain ways - figure out what principles and design/coding guidelines the Lua community uses, and follow those.
I type check public functions in my api. But do not for only internally used functions.
Good type checking:
function ( a , b )
assert ( type ( a ) == "number" , "Invalid a" )
b = b or {}
assert ( type ( b ) == "table" , "B must be a table" )
c = assert ( type ( c ) == "string" ) and c or "default"
end
Keep in mind though, lua also has a bit of "duck" typing: if all that is required in an object is callable, then a table with a __call method should be allowable. Same for an indexable object: a table and a userdata can both be indexed (not to mention the other types).
I don't know Lua either, and it's a little unclear whether you're asking only about checking the argument types [type(b)~="function"] or do you want to check their values too [a==nil], but here's what I do:
If the function can only ever be called by some other functions of your own, and those other functions have already checked the argument, then there's no need to check it again. On the other hand, if your design doesn't guarantee the safety of your arguments then you do need to check it yourself.
Basically, what can go wrong will go wrong, but it will wait until after you've finished testing and have shipped. You can't take chances - you do need a cast-iron guarantee. The key to choosing your guarantee is to inspect your design and see what you really need.
(Even if the function is only called by your own other functions, you might still want to include checks if you think you might later forget about all this and call it from somewhere else without checking.)
I guess it depends on what you plan to do next: if other people should actually write Lua code to work with your code, it would be useful to check arguments (or make it possible by having something like enableDebug). Something useful I came along yesterday is DecoratorsAndDocstrings which makes it possible to document/typecheck functions without altering the implementation.
Another idiom used for this purpose is :
argument = argument or default -- or
argument = type(argument)=="number" and argument or error'I should get a number'
Now we are unsure of what solution is better and decided to ask you: Security checks in Lua - yes or no?
It depends on the type of the project. If your project is small - i.e. only you and your teammate are going to manage it - it is OK to skip the checks, because you should know that you are passing to functions, and it will make the code small and readable. The downside is that when error occurs - and it may happen somewhere totally unexpected - you'll have to spend time debugging and tracing your functions.
On the other hand, if you are creating an library/API to be used by others, it is very appropriate to do type checking. For the user of your library who doesn't know of the internals, it is very helpful to know when he is passing the wrong arguments.
You need to check types where it is important (and should not check where it is not important). Usually I type-check most of the public function arguments plus I add a check anywhere I encounter a type error when debugging.
To shorten the type checks, I use a small arguments() helper function:
https://github.com/lua-nucleo/lua-nucleo/blob/master/lua-nucleo/args.lua
Example:
https://github.com/lua-aplicado/lua-aplicado/blob/master/lua-aplicado/filesystem.lua#L63-66
local write_file = function(filename, new_data)
arguments(
"string", filename,
"string", new_data
)
local file, err = io.open(filename, "w")
if not file then
return nil, err
end
file:write(new_data)
file:close()
file = nil
return true
end

Resources