2012-08-08 11 views

Antwort

17

Sie können das tun, indem Sie eine neue Einschränkung hinzufügen, die das von Z3 zurückgegebene Modell blockiert. Angenommen, in dem von Z3 zurückgegebenen Modell haben wir x = 0 und y = 1. Dann können wir dieses Modell blockieren, indem wir die Bedingung Or(x != 0, y != 1) hinzufügen. Das folgende Skript macht den Trick. Sie können es online ausprobieren unter: http://rise4fun.com/Z3Py/4blB

Beachten Sie, dass das folgende Skript ein paar Einschränkungen hat. Die Eingabeformel darf keine nicht interpretierten Funktionen, Arrays oder nicht interpretierten Sortierungen enthalten.

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

Ich möchte auch fragen, ist das gleiche möglich in Z3 SMT Spracherweiterung? –

+1

Nein, ist es nicht. Ich denke jedoch, es ist eine gute Idee, diesen Befehl im SMT 2.0-Front-End hinzuzufügen. –

+0

Können Sie eine Notiz hinzufügen, um zu erklären, warum nicht interpretierte Funktionen und Arrays bei dieser Methode nicht unterstützt werden? Ist es eine zufällige Einschränkung (die Datenstrukturen sind nicht ExprRefs oder etwas anderes) oder eine grundlegendere? – EfForEffort

Verwandte Themen