In Z3Py, come posso controllare se l'equazione per i vincoli dati ha una sola soluzione?(Z3Py) verifica tutte le soluzioni per l'equazione
Se più di una soluzione, come posso elencare?
In Z3Py, come posso controllare se l'equazione per i vincoli dati ha una sola soluzione?(Z3Py) verifica tutte le soluzioni per l'equazione
Se più di una soluzione, come posso elencare?
Potete farlo con l'aggiunta di un nuovo vincolo che blocca il modello restituito da Z3. Ad esempio, supponiamo che nel modello restituito da Z3 ci sia quello x = 0
e y = 1
. Quindi, possiamo bloccare questo modello aggiungendo il vincolo Or(x != 0, y != 1)
. Il seguente script fa il trucco. Puoi provare online all'indirizzo: http://rise4fun.com/Z3Py/4blB
Si noti che il seguente script presenta un paio di limitazioni. La formula di input non può includere funzioni non interpretate, array o tipi non interpretati.
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
Vorrei anche chiedere, è lo stesso possibile nell'estensione di linguaggio SMT di Z3? –
No, non lo è. Tuttavia, penso che sia una buona idea aggiungere questo comando nel front-end SMT 2.0. –
È possibile aggiungere una nota per spiegare perché le funzioni e gli array non interpretati non sono supportati utilizzando questo metodo? È una limitazione accidentale (le strutture dati non sono ExprRefs, o qualcosa del genere) o una più fondamentale? – EfForEffort