我认为一般情况下您无法做到这一点;也就是说,当您可以对任意理论进行任意约束时。您在问一个“元”问题:“最大化模型数量”不是关于问题本身的问题,而是关于问题模型的问题; 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 求解不能神奇地自动化该部分。 (除非帕特里克想出一个聪明的编码,否则他很聪明!)