z3在这个方程组中失效
多年来,我一直在跟踪解决技术问题——关于将它们应用于一个特定的难题——“跨越梯子” 为了开门见山,我无意中发现了z3,并尝试将其用于具体问题。我使用了Python绑定,并编写了以下内容:z3在这个方程组中失效,z3,z3py,Z3,Z3py,多年来,我一直在跟踪解决技术问题——关于将它们应用于一个特定的难题——“跨越梯子” 为了开门见山,我无意中发现了z3,并尝试将其用于具体问题。我使用了Python绑定,并编写了以下内容: $ cat laddersZ3.py #!/usr/bin/env python from z3 import * a = Int('a') b = Int('b') c = Int('c') d = Int('d') e = Int('e') f = Int('f') solve( a>0,
$ cat laddersZ3.py
#!/usr/bin/env python
from z3 import *
a = Int('a')
b = Int('b')
c = Int('c')
d = Int('d')
e = Int('e')
f = Int('f')
solve(
a>0, a<200,
b>0, b<200,
c>0, c<200,
d>0, d<200,
e>0, e<200,
f>0, f<200,
(e+f)**2 + d**2 == 119**2,
(e+f)**2 + c**2 == 70**2,
e**2 + 30**2 == a**2,
f**2 + 30**2 == b**2,
a*d == 119*30,
b*c == 70*30,
a*f - 119*e + a*e == 0,
b*e - 70*f + b*f == 0,
d*e == c*f)
这个问题至少有这个整数解:a=34,b=50,c=42,d=105,e=16,f=40
是我做错了什么,还是这种方程组/范围约束超出了z3所能解决的范围
提前感谢您的帮助
更新,5年后:Z3现在可以直接解决这个问题。如果您将整数编码为实数,则可以使用Z3解决这个问题,这将迫使Z3使用非线性实数算术解算器。有关非线性整数与实数算术解算器的更多详细信息,请参见: 下面是您的示例,使用解决方案编码为reals(z3py链接:):
其中,
p
是约束的结合(z3py链接:)。与其问Z3
一个reals中的解决方案,您可以问:
解算器会在几分之一秒内得出您提到的解决方案。速成版过去是免费的,但我不确定目前的状态
a: 34
b: 50
c: 42
d: 105
e: 16
f: 40
一般来说,没有一种算法可以回答多元多项式方程(或其系统,如您的情况)是否有整数解(这是希尔伯特第十个问题的否定答案)。因此,整数的所有求解方法要么局限于某些类别(例如线性方程组、一个变量中的多项式……),要么使用不完整的技巧,例如:
- 线性化表达式
- 将方程编码为有限位宽度 数字(搜索“小”解决方案时可以)
这就是为什么Z3需要被告知使用实数解算器。这个问题也出现在Z3问题列表中:谢谢!在您链接的SO文章中,提到可以使用“(check sat using qfnra nlsat)”以某种方式要求额外检查解决方案是否真的将整数值分配给变量。有没有办法通过Python绑定到z3来实现这一点?是的,您可以使用
solve\u和从策略()创建的自定义解算器来实现这一点。下面是一个例子:
a,b,c,d,e,f = Reals('a b c d e f')
solve(
a>0, a<200,
b>0, b<200,
c>0, c<200,
d>0, d<200,
e>0, e<200,
f>0, f<200,
(e+f)**2 + d**2 == 119**2,
(e+f)**2 + c**2 == 70**2,
e**2 + 30**2 == a**2,
f**2 + 30**2 == b**2,
a*d == 119*30,
b*c == 70*30,
a*f - 119*e + a*e == 0,
b*e - 70*f + b*f == 0,
d*e == c*f) # yields [a = 34, b = 50, c = 42, d = 105, e = 16, f = 40]
t = Then('purify-arith','nlsat')
s = t.solver()
solve_using(s, P)
using Microsoft.SolverFoundation.Services;
static Term sqr(Term t)
{
return t * t;
}
static void Main(string[] args)
{
SolverContext context = SolverContext.GetContext();
Domain range = Domain.IntegerRange(1, 199); // integers ]0; 200[
Decision a = new Decision(range, "a");
Decision b = new Decision(range, "b");
Decision c = new Decision(range, "c");
Decision d = new Decision(range, "d");
Decision e = new Decision(range, "e");
Decision f = new Decision(range, "f");
Model model = context.CreateModel();
model.AddDecisions(a, b, c, d, e, f);
model.AddConstraints("limits",
sqr(e+f) + d*d == 119*119,
sqr(e+f) + c*c == 70*70,
e*e + 30*30 == a*a,
f*f + 30*30 == b*b,
a*d == 119*30,
b*c == 70*30,
a*f - 119*e + a*e == 0,
b*e - 70*f + b*f == 0,
d*e == c*f);
Solution solution = context.Solve();
Report report = solution.GetReport();
Console.WriteLine("a={0} b={1} c={2} d={3} e={4} f={5}", a, b, c, d, e, f);
Console.Write("{0}", report);
}
a: 34
b: 50
c: 42
d: 105
e: 16
f: 40