Z3py SMT coding following variables and the formulas - z3

I am really new to Z3 and SMT solvers.
I have the following problem which I don't know how to code in Z3py.
In the above diagram N is set of nodes, thus N = {Node1, Node2, Node3, Node4, Node5, Node6, Node7}
I is set of Inputs, I = {I1, I2, I3, I4}
O is set of Outputs, O = {O1, O2, O3}
G is a group where for any consecutive 2 outputs (Oi, Oj), if Oi is first output generated and Oj is second output generated then, Gk is set of nodes that were scheduled after the generation of Oi and before the generation of Oj, but if Oj was generated before Oi then Gk contains all the blocks that were scheduled before Oj was generated.
The scheduling of the nodes is given by another program.
For example in the above block diagram the scheduling of nodes along with generation of output is as follows:
First node scheduled = Node1
Second node scheduled = Node2
Third node scheduled = Node5
Output generated = O1
Fourth node scheduled = Node3
Fifth node scheduled = Node6
Output generated = O2
Sixth node scheduled = Node4
Fifth node scheduled = Node7
Output generated = O3
Thus from above we can say that G1 for (O1, O2) is = {Node3, Node6}
But G2 for (O2, O1) is = {Node1, Node2, Node5}
To execute each node we need a task, a task can implement 1 node or a set of nodes at a time.
Noder,i denotes ith node in group Gr.
Taskr,m denotes mth task in group Gr.
The boolean variables (can either be 0 or 1) :
fNoder,iTaskr,m represents if
Noder,i is mapped to Taskr,m
DNNoder,iNodes,j represents if
Nodes,j depends on Noder,i i.e. if there is a path from Noder,i to Nodes,j
DTTaskr,mTasks,n represents if
Tasks,n depends on Taskr,m
MTaskr,m represents if there is any node mapped on to Taskr,m
Based on the above information I have to formulate the following equations in SMT.
Minimize ( Σr,m
MTaskr,m )
MTaskr,m >=
fNoder,iTaskr,m (for all i)
Σm
fNoder,iTaskr,m = 1 (for all r != I,O)
example: fNoder,iTaskr,m + fNoder,iTaskr,m+1 + fNoder,iTaskr,m+2 = 1 + 0 + 0 = This tells us that Noder,i is mapped to Taskr,m since fNoder,iTaskr,m = 1 (only one node can be mapped to 1 task at a time but a task can be mapped to several nodes at a time)
fNoder,iTasks,m = 0 (for all r != s)
fNoder,iTaskr,m = 1 (for all r = I,O and m = i)
fNoder,iTaskr,m = 0 (for all r = I,O and m != i)
DTTaskr,mTasks,n >= fNoder,iTaskr,m + fNodes,jTasks,n + DNNoder,iNodes,j - 2
DTTaskr,mTasks,n >= DTTaskr,mTaskt,l + DTTaskt,lTasks,n - 1
DTTaskr,mTasks,n + DTTasks,nTaskr,m <= 1
I don't understand how to represent the variables and these formulas in SMT format.

I am not sure how to best answer because the question contains a lot of references to specifics that are not fully specified.
For example, what is I, and O?
You probably are asking how to add a system of linear inequalities. Or how to specify problems with integer variables that can be either 0 or 1.
One approach is to introduce functions as follows:
a = Function('a', IntSort(), IntSort(), IntSort())
Then 'a' is a function that maps pairs of integers to an integer.
You can declare function 'n' in a similar way (but I guess your example actually has some typos and you use n both as a function and as an index variable).
You can declare functions f, h, q in similar ways too.
Then in python you can write:
N = 5
s = Solver() # create a solver context
for r in range(N):
for i in range(N):
for m in range(N):
if m != i:
s.add(f(n(r,i),a(r,m)) == 0)
This adds the equality constraints on f that you specified.
The other equality and inequality constraints can be added in similar ways.
In the end you ask whether the resulting state is satisfiable.
print s.check()
print s.model() # print model for satisfiable outcome.
Other approaches are that you declare distinct constants for the different
versions of f. After all your suggested problem indicates that you are just
writing down a large system of inequalities over variables created in different
ways.
E.g., you can create and the constant v:
v = Const('f(a[%d][%d],a[%d][%d])' % (r,m,r,i), IntSort())
instead of the function application.

Related

I can't figure out how to do an simple algoritm to get the sum of two numbers

I am trying to find a solution to the problem "Two Sum" if you recognize it , and I've run into a problem and I cannot figure it out (Lua)
Code:
num = {2,7,11,15}
target = 9
current = 0
repeat
createNum1 = tonumber(num[math.random(1,#num)])
createNum2 = tonumber(num[math.random(1,#num)])
current = createNum1 + createNum2
until current == target
print(table.find(num,createNum1), table.find(num,createNum2))
Error:
lua5.3: HelloWorld.lua:9: attempt to call a nil value (field 'find')
stack traceback:
HelloWorld.lua:9: in main chunk
[C]: in ?
Thank you!
Lua has no table.find function in its very small standard library; just take a look at the reference manual.
You could implement your own table.find function, but that would just be monkey-patching an overall broken algorithm. There is no need to use a probabilistic algorithm that probably runs in at least quadratic time if there only is one pair of numbers that adds up to the desired number. Instead, you should leverage Lua's tables - associative arrays - here. First build an index of [number] = last index:
local num = {2,7,11,15}
local target = 9
local idx = {}
for i, n in ipairs(num) do idx[n] = i end
then loop over the numbers; given a number m you just need to look for target - m in your idx lookup:
for i, n in ipairs(num) do local j = idx[target - n]; if j then print(i, j) break end end
if you want to exit early - sometimes without building the full idx table - you can fuse the two loops:
local idx = {}
for i, n in ipairs(num) do
local j = idx[target - n]
if j then
print(j, i)
break
end
idx[n] = i
end
other solutions exist (e.g. using sorting, which requires no auxiliary space), but this one is elegant in that it runs in O(n) time & O(n) space to produce a solution and leverages Lua's builtin data structures.

Picking a chosen amount of things from a table without repetition

So I'm currently working on a little side project, so this is my first time learning LUA and I'm currently stuck. So what I'm trying to do is create a function that will randomly choose two numbers between 1 and 5 and make it so they can not collide with the player. I can not seem to get the ability to chose two numbers at random without them being the same. I've been looking around, but have not been able to find a clear answer. Any help would be much appreciated!
My code so far:
local function RandomChoice1()
local t = {workspace.Guess1.CB1,workspace.Guess1.CB2,workspace.Guess1.CB3,workspace.Guess1.CB4,workspace.Guess1.CB5}
local i = math.random(1,5)
end
If you need to select one with probability 20% (one from 1..5 range) and the second one with probability 25% (one from 1..5 range minus the first choice), then something like this should work:
local i1 = math.random(1,5) -- pick one at random from 1..5 interval
-- shift the interval up to account for the selected item
local i2 = math.random(2,5) -- pick one at random from 2..5 interval
-- assign 1 in case of a collision
if i2 == i1, then i2 = 1 end
This will guarantee the numbers not being equal and satisfying your criteria.
Instead of generating i2 you can generate difference i2 - i1
local i1 = math.random(5) -- pick one at random from 1..5 interval
local diff = math.random(4) -- pick one at random from 1..4 interval
local i2 = (i1 + diff - 1) % 5 + 1 -- from 1..5 interval, different from i1
print(i1, i2)
You could use recursion. Save the previous number and if it's the same just generate a new one until its not the same. This way you are garaunteed to never have the same number twice.
local i = 0;
function ran(min,max)
local a = math.random(min,max);
if (a == i) then
return ran(min,max);
else
i = a;
return a;
end
end
Example: "2 from 5" without doubles...
local t = {}
for i = 1, 5 do
t[i] = i
end
-- From now a simple table.remove()...
-- ( table.remove() returns the value of removed key/value pair )
-- ...on a random key avoids doubles
for i = 1, 2 do
print(table.remove(t, math.random(#t)))
end
Example output...
1
4

Need to sum the numbers 1 through 100, how to write a loop to complete the operation?

I'm learning Lua from a book and this is the exact question I'm stuck on:
Given that you need to sum the numbers 1 through 100, write a loop to complete the operation.
I've tried various things, but my most recent attempt following:
n = 1
while (n < 100) do
n = n + 1
print (n)
end
As mentioned earlier, you need at least two variables: one to hold sum and second to count to 100.
Fixed steps calculations is better to do with for loop.
local sum = 0
for i = 1, 100 do
sum = sum + i
end
print(sum)
P.S. Where is the question? Add not only broken code, but some words about what is wrong with it please.
It looks like you need to do something like this:
local n = 1
local sum = 0
while (n <= 100) do
sum = sum + n
n = n + 1
end
print(sum)
It should help if you keep your sum and counter in separate variables.
You need another variable to hold the sum :)
I believe this should do it:
i=0
n=0
while i <= 100 do
n = i + n
i = i + 1
end
print(n)
Variables are visible after they their first assignment. So you need one variable declared outside the loop to hold the sum as it is updated inside the loop, like this:
n = 0
sum = 0
while (n < 100) do
n = n + 1 -- n variable output is 1,2,3,4,5,...100
sum = sum + n -- sum variable remembers its value from previous iteration
print (sum)
end
When you do sum = sum + n, the interpreter takes the current value of sum, adds n to it, and puts the result into sum. At next iteration, sum still has that most recent value. Compare, if you had done
while (n < 100) do
n = n + 1 -- n variable output is 1,2,3,4,5,...100
local sum = sum + n -- sum is "new" at every iteration so fails
print (sum)
end
This sum variable is local to loop so every time through loop, a new sum is created. Only problem is,
local sum = sum + n
that statement tries to get value of "sum" and add it to n, but sum is being created on that line so it doesn't exist yet so interpreter will throw error about attempt to do arithmetic on global "sum" (the sum that appears on right hand side is not know to compiler so it thinks it is a global since it hasn't created the local sum yet).
All previous answers ignore that sum can be calculated using a single equation;
Assume largest number is "N"
Sum of integers from 1 to N is; ( N x ( N + 1 )) / 2

Can Z3 call python function during decision making of variables?

I am trying to solve a problem, for example I have a 4 point and each two point has a cost between them. Now I want to find a sequence of nodes which total cost would be less than a bound. I have written a code but it seems not working. The main problem is I have define a python function and trying to call it with in a constraint.
Here is my code: I have a function def getVal(n1,n2): where n1, n2 are Int Sort. The line Nodes = [ Int("n_%s" % (i)) for i in range(totalNodeNumber) ] defines 4 points as Int sort and when I am adding a constraint s.add(getVal(Nodes[0], Nodes[1]) + getVal(Nodes[1], Nodes[2]) < 100) then it calls getVal function immediately. But I want that, when Z3 will decide a value for Nodes[0], Nodes[1], Nodes[2], Nodes[3] then the function should be called for getting the cost between to points.
from z3 import *
import random
totalNodeNumber = 4
Nodes = [ Int("n_%s" % (i)) for i in range(totalNodeNumber) ]
def getVal(n1,n2):
# I need n1 and n2 values those assigned by Z3
cost = random.randint(1,20)
print cost
return IntVal(cost)
s = Solver()
#constraint: Each Nodes value should be distinct
nodes_index_distinct_constraint = Distinct(Nodes)
s.add(nodes_index_distinct_constraint)
#constraint: Each Nodes value should be between 0 and totalNodeNumber
def get_node_index_value_constraint(i):
return And(Nodes[i] >= 0, Nodes[i] < totalNodeNumber)
nodes_index_constraint = [ get_node_index_value_constraint(i) for i in range(totalNodeNumber)]
s.add(nodes_index_constraint)
#constraint: Problem with this constraint
# Here is the problem it's just called python getVal function twice without assiging Nodes[0],Nodes[1],Nodes[2] values
# But I want to implement that - Z3 will call python function during his decission making of variables
s.add(getVal(Nodes[0], Nodes[1]) + getVal(Nodes[1], Nodes[2]) + getVal(Nodes[2], Nodes[3]) < 100)
if s.check() == sat:
print "SAT"
print "Model: "
m = s.model()
nodeIndex = [ m.evaluate(Nodes[i]) for i in range(totalNodeNumber) ]
print nodeIndex
else:
print "UNSAT"
print "No solution found !!"
If this is not a right way to solve the problem then could you please tell me what would be other alternative way to solve it. Can I encode this kind of problem to find optimal sequence of way points using Z3 solver?
I don't understand what problem you need to solve. Definitely, the way getVal is formulated does not make sense. It does not use the arguments n1, n2. If you want to examine values produced by a model, then you do this after Z3 returns from a call to check().
I don't think you can use a python function in your SMT logic. What you could alternatively is define getVal as a Function like this
getVal = Function('getVal',IntSort(),IntSort(),IntSort())
And constraint the edge weights as
s.add(And(getVal(0,1)==1,getVal(1,2)==2,getVal(0,2)==3))
The first two input parameters of getVal represent the node ids and the last integer represents the weight.

Lua base converter

I need a base converter function for Lua. I need to convert from base 10 to base 2,3,4,5,6,7,8,9,10,11...36 how can i to this?
In the string to number direction, the function tonumber() takes an optional second argument that specifies the base to use, which may range from 2 to 36 with the obvious meaning for digits in bases greater than 10.
In the number to string direction, this can be done slightly more efficiently than Nikolaus's answer by something like this:
local floor,insert = math.floor, table.insert
function basen(n,b)
n = floor(n)
if not b or b == 10 then return tostring(n) end
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local t = {}
local sign = ""
if n < 0 then
sign = "-"
n = -n
end
repeat
local d = (n % b) + 1
n = floor(n / b)
insert(t, 1, digits:sub(d,d))
until n == 0
return sign .. table.concat(t,"")
end
This creates fewer garbage strings to collect by using table.concat() instead of repeated calls to the string concatenation operator ... Although it makes little practical difference for strings this small, this idiom should be learned because otherwise building a buffer in a loop with the concatenation operator will actually tend to O(n2) performance while table.concat() has been designed to do substantially better.
There is an unanswered question as to whether it is more efficient to push the digits on a stack in the table t with calls to table.insert(t,1,digit), or to append them to the end with t[#t+1]=digit, followed by a call to string.reverse() to put the digits in the right order. I'll leave the benchmarking to the student. Note that although the code I pasted here does run and appears to get correct answers, there may other opportunities to tune it further.
For example, the common case of base 10 is culled off and handled with the built in tostring() function. But similar culls can be done for bases 8 and 16 which have conversion specifiers for string.format() ("%o" and "%x", respectively).
Also, neither Nikolaus's solution nor mine handle non-integers particularly well. I emphasize that here by forcing the value n to an integer with math.floor() at the beginning.
Correctly converting a general floating point value to any base (even base 10) is fraught with subtleties, which I leave as an exercise to the reader.
you can use a loop to convert an integer into a string containting the required base. for bases below 10 use the following code, if you need a base larger than that you need to add a line that mapps the result of x % base to a character (usign an array for example)
x = 1234
r = ""
base = 8
while x > 0 do
r = "" .. (x % base ) .. r
x = math.floor(x / base)
end
print( r );

Resources