Z3py SMT编码遵循变量和公式

Z3py SMT coding following variables and the formulas

我对 Z3 和 SMT 求解器真的很陌生。 我有以下问题,我不知道如何在 Z3py 中编码。

在上图中,N 是一组节点,因此 N = {Node1, Node2, Node3, Node4, Node5, Node6, Node7}

I 是一组输入,I = {I1, I2, I3, 我4}

O 是一组输出,O = {O1, O2, O3}

G是一个组,其中对于任何连续的2个输出(Oi,Oj),如果O i 是第一个生成的输出,Oj 是第二个生成的输出,Gk 是在Oi 的生成和 Oj 的生成之前,but if O j 在 Oi 之前生成然后 Gk 包含在 Oj[ 之前调度的所有块=183=] 已生成。 节点的调度由另一个程序给出。 例如,在上面的框图中,节点的调度以及输出的生成如下:

因此从上面我们可以说 G1 for (O1, O2) = {Node3, Node6}

但是 G2 对于 (O2, O1) 是 = {Node1 , 节点 2, 节点 5}

要执行每个节点我们需要一个任务,一个任务一次可以执行一个节点或一组节点。

节点r,i表示组Gr中的第i个节点。 Taskr,m表示组Gr.

中第mth个任务

布尔变量(可以是 0 或 1):

根据以上信息,我必须在 SMT 中制定以下等式。

  1. 最小化 ( Σr,m M任务r,m)
  2. M任务r,m >= fNoder,iTaskr,m (for all i)
  3. Σm fNoder,iTaskr,m = 1(对于所有 r != I,O ) 示例: fNoder,iTaskr, m + f节点r,i任务r,m+1 + f节点r,i任务r,m+2 = 1 + 0 + 0 = 这告诉我们 Noder,i 被映射到 Taskr,m 因为 fNode r,iTaskr,m = 1(一次只能将一个节点映射到1个任务,但一个任务可以映射到多个一个节点)
  4. fNoder,iTasks,m = 0(对于所有 r != s)
  5. fNoder,iTaskr,m = 1(对于所有 r = I,O 和 m = i)
  6. fNoder,iTaskr,m = 0(对于所有 r = I,O 和 m != i)
  7. DT任务r,m任务s,n >= f节点r,i任务r,m + f节点s, j任务s,n + DN节点r,i节点s,j - 2
  8. DT任务r,m任务s,n >= DT任务r,m任务t,l + DT任务t, l任务s,n - 1
  9. DT任务r,m任务s,n + DT任务s,n任务r,m <= 1

我不明白如何用 SMT 格式表示变量和这些公式。

我不确定如何最好地回答这个问题,因为该问题包含很多未完全指定的细节参考。 例如,I 和 O 是什么? 您可能会问如何添加线性不等式系统。或者如何指定可以为 0 或 1 的整数变量的问题。

一种方法是引入函数如下:

       a = Function('a', IntSort(), IntSort(), IntSort())

然后'a'是一个将整数对映射到整数的函数。 您可以用类似的方式声明函数 'n' (但我猜您的示例实际上有一些拼写错误,并且您将 n 既用作函数又用作索引变量)。 您也可以用类似的方式声明函数 f、h、q。

然后在python中可以这样写:

     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)

这会在您指定的 f 上添加等式约束。 可以用类似的方式添加其他等式和不等式约束。 最后你问结果状态是否可满足。

    print s.check()
    print s.model()   # print model for satisfiable outcome.

其他方法是为不同的对象声明不同的常量 f的版本。毕竟你建议的问题表明你只是 写下一个由不同变量创建的不等式的大系统 方式。

例如,您可以创建常量 v:

    v = Const('f(a[%d][%d],a[%d][%d])' % (r,m,r,i), IntSort())

而不是函数应用程序。