Z3解算器Java API:意外行为

Z3解算器Java API:意外行为,java,z3,solver,smt,Java,Z3,Solver,Smt,通过向解算器添加条件,我想用“solver.check()”检查是否存在解。因此,我创建了一个简单的示例来找到t1的解决方案。我知道t1有一个解,即t1=0。然而,解算器没有“可满足”的状态 它输出: solver c2: UNKNOWN solver c3: UNKNOWN 突然,解决者的状态变得“令人满意”。但如果我事先只检查一个条件,状态仍然是“不可满足” 除此之外,如果我从 t1 = ctx.mkRealConst("t1"); 到 解算器也会找到解决方案,解算器状态为“可满足” 为

通过向解算器添加条件,我想用“solver.check()”检查是否存在解。因此,我创建了一个简单的示例来找到t1的解决方案。我知道t1有一个解,即t1=0。然而,解算器没有“可满足”的状态

它输出:

solver c2: UNKNOWN
solver c3: UNKNOWN
突然,解决者的状态变得“令人满意”。但如果我事先只检查一个条件,状态仍然是“不可满足”

除此之外,如果我从

t1 = ctx.mkRealConst("t1");

解算器也会找到解决方案,解算器状态为“可满足”


为什么解算器会有这种行为?我如何才能让解算器找到解决方案?有没有其他方法可以尝试?

一般来说,当你写:

solver.check(c1)
您没有要求z3检查
c1
是否满足要求。您要求z3做的是,假设
c1
为真,检查您输入的所有断言是否都是可满足的。这称为“假设下的检查”,并记录在此处:

这在一开始可能会让人相当困惑,但它允许检查假设下的可满足性,而不必全局断言这些假设

关于您为什么得到未知的
。您使用的是浮点运算,并将其与实数进行混合和匹配。这会产生很多非线性约束,z3并不能很好地处理这些约束。尽量将逻辑分开:如果可以的话,不要把实数和浮点数混合在一起。(如果您对如何建模有疑问,请单独提问。)

最后,编写
t1=ctx.mkReal(0)
与编写
t1=ctx.mkrealconts(“t1”)
非常不同。第一个更容易处理:
t1
仅为0。在第二种情况下,它是一个变量。因此,对于前者导致z3更容易处理的问题一点也不奇怪。同样,没有什么灵丹妙药,但首先不要以这种方式混合逻辑:如果你想处理浮点运算,就把所有东西都放在那块地上。如果你想用真实的价值观来工作,那就让一切都保持真实的价值。那样你会跑得更远。如果必须将两者混合使用,则很可能会看到
UNKNOWN
结果

t1 = ctx.mkRealConst("t1");
t1 = ctx.mkReal(0);
solver.check(c1)