Я не думаю, что вы можете сделать это в целом; то есть, когда вы можете иметь произвольные ограничения на произвольные теории. Вы задаете мета-вопрос: «Максимизировать количество моделей» - это не вопрос самой проблемы, а вопрос о моделях проблемы; что-то, с чем SMTLib не может справиться.
Сказав это, однако, я думаю, что должно быть возможно закодировать это для определенных проблем. В приведенном вами примере пространство модели максимизируется, когда a - b
является наибольшим; так что вы можете просто написать:
(set-option :produce-models true)
(declare-fun a () Int)
(declare-fun b () Int)
(declare-fun c () Int)
(assert (< 5 a 10))
(assert (< 0 b 5))
(assert (< b c a))
(maximize (- a b))
(check-sat)
(get-value (a b))
На что отвечает z3:
sat
((a 9)
(b 1))
по желанию. Или вы можете использовать привязки Python:
from z3 import *
a, b, c = Ints('a b c')
o = Optimize()
o.add(And(5 < a, a < 10, 0 < b, b < 5, b < c, c < a))
o.maximize(a - b)
if o.check() == sat:
m = o.model()
print "a = %s, b = %s" % (m[a], m[b])
else:
print "unsatisfiable or unknown"
который печатает:
a = 9, b = 1
Существуют также привязки для C / C ++ / Java / Scala / Haskell и т. Д., Которые позволяют вам делать более или менее то же самое с этими хостами.
Но решающим моментом здесь является то, что нам пришлось вручную придумать цель, чтобы максимизация a - b
разрешила бы проблему здесь. Этот шаг требует вмешательства человека, так как он относится к вашей текущей проблеме. (Представьте, что вы работаете с теорией поплавков или произвольными типами данных; придумать такую меру может быть невозможно.) Я не думаю, что эту часть можно волшебным образом автоматизировать с помощью традиционного решения SMT. (Если Патрик не придумает умную кодировку, он довольно умный в этом смысле!)