Please consider the following problem
(declare-fun x1 () Bool)
(declare-fun x2 () Bool)
(declare-fun x3 () Bool)
(declare-fun x4 () Bool)
(define-fun conjecture () Bool
(and (= (and x2 x3) x1) (= (and x1 (not x4)) x2) (= x2 x3) (= (not x3) x4)))
(assert conjecture)
(check-sat)
(get-model)
(assert (= x4 false))
(check-sat)
(get-model)
and the corresponding output is
sat
(model
(define-fun x2 () Bool false)
(define-fun x4 () Bool true)
(define-fun x1 () Bool false)
(define-fun x3 () Bool false) )
sat
(model
(define-fun x3 () Bool true)
(define-fun x2 () Bool true)
(define-fun x1 () Bool true)
(define-fun x4 () Bool false) )
This problem has two solutions. But, please let me know how to determine automatically the number of the possible solutions.
Other example:
(declare-fun x1 () Bool)
(declare-fun x2 () Bool)
(declare-fun x3 () Bool)
(declare-fun x4 () Bool)
(declare-fun x5 () Bool)
(define-fun conjecture () Bool
(and (= (and x2 x3 (not x4)) x1) (= (and x1 (not x4) (not x5)) x2)
(= (and x2 (not x5)) x3) (= (and (not x3) x1) x4) (= (and x2 x3 (not x4)) x5)))
(assert conjecture)
(check-sat)
(get-model)
The output is:
sat
(model
(define-fun x3 () Bool false)
(define-fun x1 () Bool false)
(define-fun x4 () Bool false)
(define-fun x5 () Bool false)
(define-fun x2 () Bool false) )
How I can to know if this solution is the only solution?
Other example online here
I am trying to apply the method proposed at Z3-number of solutions. Such method performs well in the following example:
Code:
def add_constraints(s, model):
x = Bool('x')
s.add(Or(x, False) == True)
notAgain = []
i = 0
for val in model:
notAgain.append(x != model[val])
i = i + 1
if len(notAgain) > 0:
s.add(Or(notAgain))
print Or(notAgain)
return s
s = Solver()
i = 0
add_constraints(s, [])
while s.check() == sat:
print s.model()
i = i + 1
add_constraints(s, s.model())
print i # solutions
Output :
[x = True]
x ≠ True
1
Run this example online here.
But the method fails online in the following example
def add_constraints(s, model):
x = Bool('x')
s.add(Or(x, True) == True)
notAgain = []
i = 0
for val in model:
notAgain.append(x != model[val])
i = i + 1
if len(notAgain) > 0:
s.add(Or(notAgain))
print Or(notAgain)
return s
s = Solver()
i = 0
add_constraints(s, [])
while s.check() == sat:
print s.model()
i = i + 1
add_constraints(s, s.model())
print i # solutions
Output:
F:\Applications\Rise4fun\Tools\Z3Py timed out
Run this example online here
For this last example the correct answer is 2. Please can you tell me why such method fails in this case?
Other example with the modified Taylor`s code:
def add_constraints(s, model):
X = BoolVector('x', 4)
s.add(Or(X[0], False) == X[1])
s.add(Or(X[1], False) == X[0])
s.add(Or(Not(X[2]), False) == Or(X[0],X[1]))
s.add(Or(Not(X[3]), False) == Or(Not(X[0]),Not(X[1]),Not(X[2])))
notAgain = []
i = 0
for val in model:
notAgain.append(X[i] != model[X[i]])
i = i + 1
if len(notAgain) > 0:
s.add(Or(notAgain))
print Or(notAgain)
return s
s = Solver()
i = 0
add_constraints(s, [])
while s.check() == sat:
print s.model()
i = i + 1
add_constraints(s, s.model())
print i # solutions
Output:
[x1 = False, x0 = False, x3 = False, x2 = True]
x0 ≠ False ∨ x1 ≠ False ∨ x2 ≠ True ∨ x3 ≠ False
[x1 = True, x0 = True, x3 = False, x2 = False]
x0 ≠ True ∨ x1 ≠ True ∨ x2 ≠ False ∨ x3 ≠ False
2
Run this example online here
Many thanks.