Я столкнулся с проблемой, когда Z3Py не перечисляет все возможные решения для данных булевых предложений. Мне было интересно, если кто-нибудь знает, почему это происходит.
Вот код, который я использую для Z3Py. Есть 5 логических значений: 1 2 3 4 и 5.
from z3 import *
a,b,c,d,e = Bools('1 2 3 4 5')
solver = Solver()
solver.add(Or(Not(a), Not(b)))
solver.add(Or(Not(b), Not(c)))
solver.add(Or(Not(c), Not(d)))
solver.add(Or(Not(d), Not(e)))
while solver.check() == sat:
model = solver.model()
block = []
for declaration in model:
constant = declaration()
block.append(constant != model[declaration])
solver.append(Or(block))
solution = []
for val in model:
if is_true(model[val]):
solution.append(str(val()))
else:
solution.append('-' + str(val()))
solution.sort()
print(solution)
Это производит следующие модели:
['-1', '-2', '-3', '-4', '-5']
['-2', '-3', '-5', '1']
['-2', '-3', '-4', '1', '5']
['-2', '-4', '3', '5']
['-2', '-4', '-5', '3']
['-1', '-3', '-4', '-5', '2']
['-1', '-3', '-4', '2', '5']
['-1', '-2', '-3', '-4', '5']
['-1', '-2', '-3', '-5', '4']
['-1', '-3', '-5', '2', '4']
Если я запускаю те же пункты, используя Pycosat со следующим кодом:
import pycosat
clauses = [(-1, -2), (-2, -3), (-3, -4), (-4, -5)]
for solution in pycosat.itersolve(clauses):
print(solution)
Я получаю такие результаты:
[-1, -2, -3, -4, -5]
[-1, -2, -3, -4, 5]
[-1, -2, -3, 4, -5]
[-1, -2, 3, -4, -5]
[-1, -2, 3, -4, 5]
[-1, 2, -3, -4, -5]
[-1, 2, -3, -4, 5]
[-1, 2, -3, 4, -5]
[1, -2, -3, 4, -5]
[1, -2, -3, -4, -5]
[1, -2, -3, -4, 5]
[1, -2, 3, -4, -5]
[1, -2, 3, -4, 5]
Следовательно, Z3Py упускает 3 возможных решения на основе результатов Pycosat. А это:
[1, -2, 3, -4, 5]
[1, -2, -3, 4, -5]
[1, -2, 3, -4, -5]
Я знаю, что это разные решатели, но, основываясь на одних и тех же предложениях, используемых для них обоих, я ожидаю, что результаты совпадут. Кто-нибудь знает, почему Z3Py пропустит эти решения в этом случае?
Другое дело, что не все решения в Z3Py содержат все определенные переменные.