Z3 如何检查1000+;没有重复值的变量?

Z3 如何检查1000+;没有重复值的变量?,z3,Z3,我是Z3新手,对于一个开源程序,我想使用Z3解算器来提高效率 我有大约1000+个 (declare-const a1 Int) (declare-const a2 Int) (declare-const a3 Int) (declare-const a4 Int) ... 结果是什么 (declare-const x1 Int) (declare-const x2 Int) ... (assert (= (+ a1 a2) x1) // in reality its not "plus"

我是Z3新手,对于一个开源程序,我想使用Z3解算器来提高效率

我有大约1000+个

(declare-const a1 Int)
(declare-const a2 Int)
(declare-const a3 Int)
(declare-const a4 Int)
...
结果是什么

(declare-const x1 Int)
(declare-const x2 Int)
...
(assert (=  (+ a1 a2) x1) // in reality its not "plus" but more sophisticated
(assert (=  (+ a3 a4) x2) // however for simplicity lets keep it at that here.
...
现在我想确保所有x1到x500+变量都有不同的值,并且没有重复项

我当然可以

(assert (not (= x1 x2)))
(assert (not (= x1 x3)))
(assert (not (= x1 x4)))
...
(assert (not (= x2 x3)))
(assert (not (= x2 x4)))
...
(assert (not (= x718 719)))
这是可行的,但有更好的解决办法吗


非常感谢

您可以使用
distinct
(参见此):

好了,这通常是在一系列不等式中进行内部扩展的,就像您在示例中介绍的那样


讨论:下面是关于这种编码效率的纯理论讨论
z3
是一个非常高效的SMT求解器,因此您可能不需要尝试任何比运行该工具更复杂的方法

等式的否定(例如,
(非(=x y))
)通常被分成一对不等式:

x < y \/ x > y

现在,考虑到你的问题,你会得到数百个这样的子句。这些都在线性算术级别上相互关联,但在SAT引擎运行的布尔级别上不相关。因此,SAT引擎可能会生成(大量)不一致的部分真值赋值,这些赋值通常会违反
变量的传递性属性,可以使用数组,试试看,但这是如何工作的?我看不到,请提供一个简短的示例distinct关键字工作得很好,结果是模型的行数减少了很多!:)但是,它没有减少执行时间以找到解决方案(这很可怕:-()。我希望能够将每个结果写入其数组索引,将其中的值增加1,如果任何数组值不是0或1,则会有一个副本-这将快得多。但我在z3中看不到如何执行该操作。我可以执行IFE语句,但这只允许我返回值,而不是例如@vhthc您可以计算nu使用伪布尔约束具有相同值的变量数。我稍后将编辑我的答案。我不确定它是否可以缩短搜索时间,因为每个基数约束的复杂性将是N*LOG(N)。我实现并测试了“distinct”解决方案-正如您所说,然后我阅读了有关它的文档-它应该与我的百万行
(assert(不是(=x2 x4))…(assert(不是(=x718 719)))
相同,但是在超过8小时后它仍然没有完成计算。然而,我的百万行解决方案在40分钟内完成(这仍然是可以接受的10倍以上)。因此,内部发生的任何情况实际上都是非常不同的,这使得解决方案无法使用:-(damnI不能使用基数约束,因为值范围至少为0-65535,并且通常大于该值。我现在插入了这样的约束:
(assert(>=x10))(assert(
并将检查它如何改进speed@vhthc除非在内部生成一百万个子句需要几个小时,这是一个非常有趣的否定结果;如果没有一个来自代码> Z3团队将在一个星期内发布,我会考虑尝试在他们的存储库中提交一个bug报告,看看他们会怎么回答。e、 请回到这里,并添加一个链接到错误报告,以便其他人可以跟随讨论!
x < y \/ x > y
B1 \/ B2
 x < y /\ y < z /\ z < x
x1 < x2 /\ x2 < x3 /\ ... /\ x499 < x500
(assert
    ((_ at-most 1)
     (= x1 0)
     (= x2 0)
     ...
     (= x500 0)
    )
)
...
% repeat for all possible values 
...