Когда вы говорите «Exists», а затем «Forall», вы говорите, что формула должна быть истинной для каждого такого x0
, x1
. И Z3 говорит вам, что это просто не так.
Если вы заинтересованы в поиске одного такого P
и соответствующих x
значений, просто отбросьте квантификацию и сделайте все переменной верхнего уровня:
from z3 import *
def f(x0, x1, P0, P1, P2, P3):
return P0*x0*x0 + P1*x0*x1 + P2*x0*x1 + P3*x1*x1
def g(x0, x1, P0, P1, P2, P3):
return -2*P0*x0*x1 + P1*x0*x0 - P1*x0*x1 - P1*x1*x1 + P2*x0*x0 - P2*x0*x1 - P2*x1*x1 + 2*P3*x0*x1 - 2*P3*x1*x1
p0, p1, p2, p3 = Reals('p0 p1 p2 p3')
x0, x1 = Reals('x0 x1')
fmls = [Implies(Or(x0 != 0, x1 != 0), And(f(x0, x1, p0, p1, p2, p3) > 0, g(x0, x1, p0, p1, p2, p3) < 0))]
while True:
s = Solver()
s.add(fmls)
res = s.check()
print res
if res == sat:
m = s.model()
print m
fmls += [Or(p0 != m[p0], p1 != m[p1])]
else:
print "giving up"
break
Когда я запускаю это, я получаю:
sat
[x0 = 1/8, p0 = -1/2, p1 = -1/2, x1 = 1/2, p2 = 1, p3 = 1]
и многие другие; что я верю, что вы после.
Обратите внимание, что вы также можете заняться программированием, чтобы избавиться от экзистенциального количественного определения в зависимости от того, где вы находитесь; то есть, начните с количественной версии, если вы получите unsat
, затем переключитесь на новый решатель и используйте не количественную версию, чтобы автоматизировать этот процесс. Конечно, это всего лишь программирование, и на данный момент оно не имеет ничего общего с z3.