2012-11-15 12 views
18

Próbuję odzyskać wszystkie możliwe modele dla niektórych teorii pierwszego rzędu za pomocą Z3, solver SMT opracowany przez Microsoft Research. Oto minimalne przykład roboczych:Z3: znajdowanie wszystkich satysfakcjonujących modeli

(declare-const f Bool) 
(assert (or (= f true) (= f false))) 

W tym przypadku zdań istnieją dwa satysfakcjonujące zadania: f->true i f->false. Ponieważ Z3 (i ogólnie solucje SMT) będą próbować znaleźć tylko jeden satysfakcjonujący model, znalezienie wszystkich rozwiązań nie będzie bezpośrednio możliwe. Here Znalazłem użyteczne polecenie o nazwie (next-sat), ale wygląda na to, że najnowsza wersja Z3 już tego nie obsługuje. To trochę niefortunne dla mnie i generalnie myślę, że polecenie jest całkiem użyteczne. Czy istnieje inny sposób robienia tego?

Odpowiedz

18

Jednym ze sposobów osiągnięcia tego jest użycie jednego z interfejsów API wraz z możliwością generowania modelu. Następnie można użyć wygenerowanego modelu z jednego testu sprawdzalności, aby dodać ograniczenia, aby zapobiec używaniu poprzednich wartości modelu w kolejnych kontrolach zgodności, dopóki nie będzie bardziej satysfakcjonujących zadań. Oczywiście, musisz używać sortowania skończonego (lub mieć pewne ograniczenia zapewniające to), ale możesz użyć tego z nieskończonymi sortami, jeśli nie chcesz znaleźć wszystkich możliwych modeli (np. Zatrzymaj się po wygenerowaniu wiązki) .

Oto przykład przy użyciu z3py (link do z3py skrypt: http://rise4fun.com/Z3Py/a6MC):

a = Int('a') 
b = Int('b') 

s = Solver() 
s.add(1 <= a) 
s.add(a <= 20) 
s.add(1 <= b) 
s.add(b <= 20) 
s.add(a >= 2*b) 

while s.check() == sat: 
    print s.model() 
    s.add(Or(a != s.model()[a], b != s.model()[b])) # prevent next model from using the same assignment as a previous model 

Generalnie, używając dysjunktywnej wszystkich zaangażowanych stałych powinien działać (np a i b tutaj). Wylicza wszystkie przypisania liczb całkowitych dla a i b (między 1 i 20) spełniające a >= 2b. Na przykład, jeśli mamy ograniczyć a i b leżeć między 1 i 5 Zamiast wyjście jest:

[b = 1, a = 2] 
[b = 2, a = 4] 
[b = 1, a = 3] 
[b = 2, a = 5] 
[b = 1, a = 4] 
[b = 1, a = 5] 
+0

również zobaczyć tę odpowiedź: http://stackoverflow.com/questions/11867611/z3py-checking-all -solutions-for-równanie – Taylor

+4

Czy Z3 jest stanowy w tym sensie, że odbierze to miejsce, w którym zostało przerwane na takie poszukiwania? Wydaje się, że marnowanie byłoby rozpoczynanie za każdym razem, gdy (intuicyjnie) cała praca jest dokładnie taka sama, z wyjątkiem samego końca. – GManNickG

+1

@GManNickG Dla przykładów, z których korzystałem w tej metodzie, wydaje się, że rzeczywiście jest to stanowy w tym, że znalezienie kolejnych modeli po tym pierwszym jest szybsze. Oto lista środowisk wykonawczych w milisekundach dla konkretnego przypadku z 58 modelami: '8942 801 1663 5 599 320 450 2 2 3 1 5 1377 36 5 738 162 105 1639 3 5 16 2041 27 475 953 562 746 45 151 18 4206 3416 9 850 120 3 4 12 615 593 1219 449 154 987 3 10 1365 16 438 792 1686 743 46 5 8 412 126'. Należy zauważyć, że pierwsza z nich jest zdecydowanie najdłuższa, ale pozostałe są bardziej losowe (prawdopodobnie zależy od problemu i szczęścia, jakie otrzymuje solver). –

Powiązane problemy