0
votes

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 block diagram, N contains set of nodes.

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.

  1. Minimize ( Σr,m MTaskr,m )
  2. MTaskr,m >= fNoder,iTaskr,m (for all i)
  3. Σ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)
  4. fNoder,iTasks,m = 0 (for all r != s)
  5. fNoder,iTaskr,m = 1 (for all r = I,O and m = i)
  6. fNoder,iTaskr,m = 0 (for all r = I,O and m != i)
  7. DTTaskr,mTasks,n >= fNoder,iTaskr,m + fNodes,jTasks,n + DNNoder,iNodes,j - 2
  8. DTTaskr,mTasks,n >= DTTaskr,mTaskt,l + DTTaskt,lTasks,n - 1
  9. DTTaskr,mTasks,n + DTTasks,nTaskr,m <= 1

I don't understand how to represent the variables and these formulas in SMT format.

1

1 Answers

1
votes

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.