2012-08-08 67 views

回答

17

你可以通過添加新的限制,阻止該模型由Z3返回。例如,假設在由Z3返回的模型中,我們有x = 0y = 1。然後,我們可以通過添加約束Or(x != 0, y != 1)來阻止此模型。 以下腳本可以解決這個問題。 您可以在線試用:http://rise4fun.com/Z3Py/4blB

請注意,以下腳本有一些限制。輸入公式不能包含未解釋的函數,數組或未解釋的排序。

from z3 import * 

# Return the first "M" models of formula list of formulas F 
def get_models(F, M): 
    result = [] 
    s = Solver() 
    s.add(F) 
    while len(result) < M and s.check() == sat: 
     m = s.model() 
     result.append(m) 
     # Create a new constraint the blocks the current model 
     block = [] 
     for d in m: 
      # d is a declaration 
      if d.arity() > 0: 
       raise Z3Exception("uninterpreted functions are not supported") 
      # create a constant from declaration 
      c = d() 
      if is_array(c) or c.sort().kind() == Z3_UNINTERPRETED_SORT: 
       raise Z3Exception("arrays and uninterpreted sorts are not supported") 
      block.append(c != m[d]) 
     s.add(Or(block)) 
    return result 

# Return True if F has exactly one model. 
def exactly_one_model(F): 
    return len(get_models(F, 2)) == 1 

x, y = Ints('x y') 
s = Solver() 
F = [x >= 0, x <= 1, y >= 0, y <= 2, y == 2*x] 
print get_models(F, 10) 
print exactly_one_model(F) 
print exactly_one_model([x >= 0, x <= 1, y >= 0, y <= 2, 2*y == x]) 

# Demonstrate unsupported features 
try: 
    a = Array('a', IntSort(), IntSort()) 
    b = Array('b', IntSort(), IntSort()) 
    print get_models(a==b, 10) 
except Z3Exception as ex: 
    print "Error: ", ex 

try: 
    f = Function('f', IntSort(), IntSort()) 
    print get_models(f(x) == x, 10) 
except Z3Exception as ex: 
    print "Error: ", ex 
+2

我也想問一下,在Z3的SMT語言擴展中可能是一樣的嗎? – 2012-08-08 18:30:24

+1

不,它不是。但是,我認爲在SMT 2.0前端添加此命令是一個好主意。 – 2012-08-08 19:07:22

+0

您可以添加一個註釋來解釋爲什麼使用此方法不支持未解釋的函數和數組?這是一個意外的限制(數據結構不是ExprRefs,或者其他什麼)或者是一個更基本的限制? – EfForEffort 2013-05-04 15:31:17