将Z3与具体数组一起使用

时间:2015-11-04 05:04:02

标签: z3

我想用Z3来解决这个问题:

给定两个具有相同大小且具体值的数组a和b,选择满足这些约束的索引:

0 < selection < [length of array]
forall i, a[selection] <= a[i]
forall i, b[selection] >= b[i]

我的z3py程序如下所示:

def selectIndex(array1, array2):
   n= len(a) #assume both lists are same size
   s = Solver()
   selection = Int('selection')
   i = Int('i')
   j = Int('j')
   a= Array('a', IntSort(), IntSort())
   b= Array('b', IntSort(), RealSort())

   for idx in range(n):
      Store(a, idx, array1[idx])
      Store(b, idx, array2[idx])

   constraint1 = And(selection >= 0, selection <= n)
   constraint2 = And(i >= 0, i <= n)
   constraint3 = And(j >= 0, j <= n)
   constraint4 = ForAll([i], a[selection] <= a[i])
   constraint5 = ForAll([j], b[selection] >= b[j])

   s.add(And(constraint1, constraint2, constraint3, constraint4, constraint5))

   s.check()
   m = s.model()
   return m[selection].as_long()

模型总是返回0,即使给定的输入数组只有一个选择符合约束条件。我不认为它正在使用数组a和b中的具体值。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

此示例存在多个问题,但关键的一点是Store(...)表达式不执行任何操作。 Store(...)的结果是一个新的数组表达式,表示旧数组(ab),其中一个索引(idx)已更新为新值({ {1}},array1[idx])。目前这些新数组已被丢弃,但我们可以保存它们:

array2[idx]

此外,我认为

for idx in range(n):
    a = Store(a, idx, array1[idx])
    b = Store(b, idx, array2[idx])

不应包含索引 constraint1 = And(selection >= 0, selection <= n) ,即n应为<=<i

上的约束
j

是不必要的。