Z3返回的模型不可用
如果可能的话,我想对我的代码发表第二个意见 这一问题的制约因素有:Z3返回的模型不可用,z3,Z3,如果可能的话,我想对我的代码发表第二个意见 这一问题的制约因素有: a、b、c、d、e、f是非零整数 s1=[a,b,c]和s2=[d,e,f]是集合 i,j=0..2的和s1_i+s2_j必须是一个完美的平方 我不明白为什么,但我的代码返回的模型不可用。此外,在注释以下行时: (assert (and (> sqrtx4 1) (= x4 (* sqrtx4 sqrtx4)))) (assert (and (> sqrtx5 1) (= x5 (* sqrtx5 sqrtx5)
是非零整数a、b、c、d、e、f
和s1=[a,b,c]
是集合s2=[d,e,f]
的和i,j=0..2
必须是一个完美的平方s1_i+s2_j
(assert (and (> sqrtx4 1) (= x4 (* sqrtx4 sqrtx4))))
(assert (and (> sqrtx5 1) (= x5 (* sqrtx5 sqrtx5))))
(assert (and (> sqrtx6 1) (= x6 (* sqrtx6 sqrtx6))))
(assert (and (> sqrtx7 1) (= x7 (* sqrtx7 sqrtx7))))
(assert (and (> sqrtx8 1) (= x8 (* sqrtx8 sqrtx8))))
(assert (and (> sqrtx9 1) (= x9 (* sqrtx9 sqrtx9))))
d、e、f的值为负值。没有任何约束要求他们这样做。我想知道是否有一些隐藏的约束潜入其中并破坏了模型
一个有效的预期解决方案是:
a = 3
b = 168
c = 483
d = 1
e = 193
f = 673
编辑:插入(assert(=a3))
和(assert(=b168))
将导致解算器找到正确的值。这让我更加困惑
完整代码:
(declare-fun sqrtx1 () Int)
(declare-fun sqrtx2 () Int)
(declare-fun sqrtx3 () Int)
(declare-fun sqrtx4 () Int)
(declare-fun sqrtx5 () Int)
(declare-fun sqrtx6 () Int)
(declare-fun sqrtx7 () Int)
(declare-fun sqrtx8 () Int)
(declare-fun sqrtx9 () Int)
(declare-fun a () Int)
(declare-fun b () Int)
(declare-fun c () Int)
(declare-fun d () Int)
(declare-fun e () Int)
(declare-fun f () Int)
(declare-fun x1 () Int)
(declare-fun x2 () Int)
(declare-fun x3 () Int)
(declare-fun x4 () Int)
(declare-fun x5 () Int)
(declare-fun x6 () Int)
(declare-fun x7 () Int)
(declare-fun x8 () Int)
(declare-fun x9 () Int)
;all numbers are non-zero integers
(assert (not (= a 0)))
(assert (not (= b 0)))
(assert (not (= c 0)))
(assert (not (= d 0)))
(assert (not (= e 0)))
(assert (not (= f 0)))
;both arrays need to be sets
(assert (not (= a b)))
(assert (not (= a c)))
(assert (not (= b c)))
(assert (not (= d e)))
(assert (not (= d f)))
(assert (not (= e f)))
(assert (and (> sqrtx1 1) (= x1 (* sqrtx1 sqrtx1))))
(assert (and (> sqrtx2 1) (= x2 (* sqrtx2 sqrtx2))))
(assert (and (> sqrtx3 1) (= x3 (* sqrtx3 sqrtx3))))
(assert (and (> sqrtx4 1) (= x4 (* sqrtx4 sqrtx4))))
(assert (and (> sqrtx5 1) (= x5 (* sqrtx5 sqrtx5))))
(assert (and (> sqrtx6 1) (= x6 (* sqrtx6 sqrtx6))))
(assert (and (> sqrtx7 1) (= x7 (* sqrtx7 sqrtx7))))
(assert (and (> sqrtx8 1) (= x8 (* sqrtx8 sqrtx8))))
(assert (and (> sqrtx9 1) (= x9 (* sqrtx9 sqrtx9))))
;all combinations of sums need to be squared
(assert (= (+ a d) x1))
(assert (= (+ a e) x2))
(assert (= (+ a f) x3))
(assert (= (+ b d) x4))
(assert (= (+ b e) x5))
(assert (= (+ b f) x6))
(assert (= (+ c d) x7))
(assert (= (+ c e) x8))
(assert (= (+ c f) x9))
(check-sat-using (then simplify solve-eqs smt))
(get-model)
(get-value (a))
(get-value (b))
(get-value (c))
(get-value (d))
(get-value (e))
(get-value (f))
非线性整数算法是不可判定的。这意味着没有决策过程可以决定任意非线性整数约束是可满足的。这就是z3告诉您的,当它说“未知”作为您查询的答案时 当然,这并不意味着个别案件无法得到答复。Z3在解决这些公式时采用了某些策略,但它在处理问题方面存在固有的局限性。您的问题属于这一类:Z3无法解决的问题 Z3有一个专门的NRA(非线性实数算术)策略,您可以利用它。它本质上将所有变量视为实数,解决问题(非线性实数算法是可判定的,z3可以找到所有代数实数解),然后检查结果是否为整数。如果没有,它会在reals上尝试另一种解决方案。有时,如果您碰巧找到了正确的解决方案,这种策略可以处理非线性整数问题。您可以使用以下方法触发它:
(check-sat-using qfnra)
不幸的是,在我允许它运行的时间内,它并没有解决您的特定问题。(超过10分钟)不太可能找到正确的解决方案
你真的没有很多选择。SMT解算器并不适合处理非线性整数问题。事实上,正如我上面提到的,由于不可判定性,没有任何工具可以处理任意非线性整数问题;但一些工具的表现要好于其他工具,这取决于它们使用的算法
当你告诉z3什么是a
和b
时,你基本上消除了很多非线性,其余的变得容易处理。你可以找到一系列的战术来解决你原来的问题,但是这些技巧在实践中非常脆弱,不容易被发现;因为您基本上是在搜索中引入启发式,而您无法控制其行为
旁注:您的脚本可以稍微改进。要表示一组数字都是不同的,请使用distinct谓词:
(assert (distinct (a b c)))
(assert (distinct (d e f)))
这是一个很好的答案,非常感谢。这(可悲的)完全有道理,这是我一直担心的。我实际上已经尝试过qnfra选项,但在1小时后没有任何效果。。。我会尝试另一种方法,线性银似乎不是正确的方法。我想你会在你的答案中建议一些向量编码(:Patrick:我很确定他们在寻找整数算法。模块化算法肯定会找到与实际解决方案空间无关的解决方案。我想,设置+约束上的位对于虚假解决方案来说是一个足够好的对策。可能需要再考虑一下。比你更重要;)帕特里克:也许可以使用Z3的“溢出/下溢”谓词(作为SMTLib扩展)通过位向量来陈述和获得结果。但是,根据我的经验,除非你已经对解决方案的位置有了很好的了解,否则它很快就会变成一个永无止境的附加约束来取缔错误的模型。我想知道是否有一个普遍适用的技巧,尽管我怀疑它是否存在。