如何确定给定实例的解决方案数量:代数生物学中的应用

时间:2013-05-29 18:59:48

标签: z3

请考虑以下问题

(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)

,相应的输出是

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) )

这个问题有两个解决方案。但是,请让我知道如何自动确定可能的解决方案的数量。

其他例子:

(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)

输出结果为:

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) )

我怎么知道这个解决方案是否是唯一的解决方案?

其他在线示例here

我正在尝试应用Z3-number of solutions中提出的方法。这种方法在以下示例中表现良好:

代码:

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

输出:

[x = True]
x ≠ True
1

在线here运行此示例。

但是该方法在以下示例中在线失败

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

输出:

F:\Applications\Rise4fun\Tools\Z3Py timed out

在线here

运行此示例

对于最后一个例子,正确的答案是2.请问你能告诉我为什么这种方法在这种情况下失败了?

修改泰勒代码的其他例子:

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

输出:

[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

在线here

运行此示例

非常感谢。

5 个答案:

答案 0 :(得分:3)

答案 1 :(得分:1)

看起来你的问题纯属命题。如果这不是偶然的,你可能想看一下#SAT求解器(sharpSAT,Dsharp,c2d - 仅举几例)。

答案 2 :(得分:0)

第一个例子的解决方案,使用Z3Py在线修改的Taylor代码:

代码:

def add_constraints(s, model):
X = BoolVector('x', 4)
s.add(And(X[1],X[2])==X[0])
s.add(And(X[0],Not(X[3]))== X[1])
s.add(X[1] == X[2])
s.add(Not(X[2]) == X[3])
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

输出:

[x1 = False, x3 = True, x0 = False, x2 = False]
x0 ≠ False ∨ x1 ≠ False ∨ x2 ≠ False ∨ x3 ≠ True
[x1 = True, x0 = True, x3 = False, x2 = True]
x0 ≠ True ∨ x1 ≠ True ∨ x2 ≠ True ∨ x3 ≠ False
2

在线here

运行此示例

第二个例子的解决方案,使用修改后的泰勒代码与Z3Py在线使用:

代码:

def add_constraints(s, model):
X = BoolVector('x', 5)
s.add(And(X[1],X[2],Not(X[3])) == X[0])
s.add(And(X[0],Not(X[3]),Not(X[4])) == X[1])
s.add(And(X[1],Not(X[4])) == X[2])
s.add(And(Not(X[2]),X[0]) == X[3])
s.add(And(X[1],X[2],Not(X[3])) == X[4])
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

输出:

[x0 = False, x3 = False, x4 = False, x2 = False, x1 = False]
x0 ≠ False ∨
x1 ≠ False ∨
x2 ≠ False ∨
x3 ≠ False ∨
x4 ≠ False
1

在线here

运行此示例

其他例子:

enter image description here

代码:

def add_constraints(s, model):
X = BoolVector('x', 5)
s.add(X[2] == X[0])
s.add(Or(X[2],X[4]) == X[1])
s.add(X[0]== X[2])
s.add(And(X[0],X[4]) == X[3])
s.add(And(X[2],X[3]) == X[4])
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

输出:

[x0 = False, x4 = False, x2 = False, x3 = False, x1 = False]
x0 ≠ False ∨
x1 ≠ False ∨
x2 ≠ False ∨
x3 ≠ False ∨
x4 ≠ False
[x1 = True, x0 = True, x4 = True, x3 = True, x2 = True]
x0 ≠ True ∨
x1 ≠ True ∨
x2 ≠ True ∨
x3 ≠ True ∨
x4 ≠ True
[x1 = True, x0 = True, x4 = False, x3 = False, x2 = True]
x0 ≠ True ∨
x1 ≠ True ∨
x2 ≠ True ∨
x3 ≠ False ∨
x4 ≠ False
3

在线here

运行此示例

其他例子:

enter image description here

代码:

def add_constraints(s, model):
X = BoolVector('x', 12)
s.add(Or(X[8],X[10]) == X[0])
s.add(And(Not(X[6]),X[11]) == X[1])
s.add(False == X[2])
s.add(And(X[0],Not(X[9])) == X[3])
s.add(And(X[1],Not(X[9])) == X[4])
s.add(And(X[2],Not(X[7])) == X[5])
s.add(X[3] == X[6])
s.add(X[4] == X[7])
s.add(And(X[5],Not(X[11]))== X[8])
s.add(Or(X[6], X[10]) == X[9])
s.add(And(Or(X[6],X[10]),Not(X[11])) == X[10])
s.add(And(X[7],Not(X[10])) == X[11])



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

输出:

[x11 = True,
x6 = False,
x10 = False,
x9 = False,
x8 = False,
x7 = True,
x5 = False,
x4 = True,
x3 = False,
x2 = False,
x1 = True,
x0 = False]
x0 ≠ False ∨
x1 ≠ True ∨
x2 ≠ False ∨
x3 ≠ False ∨
x4 ≠ True ∨
x5 ≠ False ∨
x6 ≠ False ∨
x7 ≠ True ∨
x8 ≠ False ∨
x9 ≠ False ∨
x10 ≠ False ∨
x11 ≠ True
[x11 = False,
x1 = False,
x5 = False,
x0 = False,
x10 = False,
x9 = False,
x4 = False,
x8 = False,
x6 = False,
x7 = False,
x3 = False,
x2 = False]
x0 ≠ False ∨
x1 ≠ False ∨
x2 ≠ False ∨
x3 ≠ False ∨
x4 ≠ False ∨
x5 ≠ False ∨
x6 ≠ False ∨
x7 ≠ False ∨
x8 ≠ False ∨
x9 ≠ False ∨
x10 ≠ False ∨
x11 ≠ False
[x11 = False,
x1 = False,
x5 = False,
x0 = True,
x10 = True,
x9 = True,
x4 = False,
x8 = False,
x6 = False,
x7 = False,
x3 = False,
x2 = False]
x0 ≠ True ∨
x1 ≠ False ∨
x2 ≠ False ∨
x3 ≠ False ∨
x4 ≠ False ∨
x5 ≠ False ∨
x6 ≠ False ∨
x7 ≠ False ∨
x8 ≠ False ∨
x9 ≠ True ∨
x10 ≠ True ∨
x11 ≠ False
3  

在线here

运行此示例

非常感谢泰勒。

答案 3 :(得分:0)

其他例子:

enter image description here

代码:

def add_constraints(s, model):
X = BoolVector('x', 23)
s.add(And(Or(X[0],X[20]),Not(X[21])) == X[0])
s.add(False == X[1])
s.add(X[1] == X[2])
s.add(And(Or(X[13],X[15],X[19],X[21]),Not(X[18])) == X[3])
s.add(X[3] == X[4])
s.add(X[0] == X[5])
s.add(X[5] == X[6])
s.add(False == X[7])
s.add(And(X[7],Not(X[20]))== X[8])
s.add(False == X[9])
s.add(And(X[9],Not(X[20])) == X[10])
s.add(And(X[0],Not(X[17])) == X[11])
s.add(And(X[11],Not(X[16])) == X[12])
s.add(X[10]==X[13])
s.add(And(X[4],Not(X[16]))== X[14])
s.add(X[22]==X[15])
s.add(Or(X[17],X[21]) == X[16])
s.add(Or(X[2],X[14]) == X[17])
s.add(X[6] == X[18])
s.add(And(X[8],Not(X[0])) == X[19])
s.add(X[12]== X[20])
s.add(And(Or(X[17],X[21]),Not(X[0])) == X[21])
s.add(False == X[22])




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))

return s


s = Solver()
i = 0
add_constraints(s, [])
while s.check() == sat:
print "State ", (i + 1)
print s.model()
i = i + 1
add_constraints(s, s.model())
print "Number of States=", (i)

输出:

State  1
[x17 = False,
x0 = False,
x16 = True,
x21 = True,
x22 = False,
x20 = False,
x19 = False,
x15 = False,
x14 = False,
x13 = False,
x12 = False,
x11 = False,
x10 = False,
x9 = False,
x8 = False,
x7 = False,
x4 = True,
x3 = True,
x18 = False,
x6 = False,
x5 = False,
x2 = False,
x1 = False]
State  2
[x11 = False,
x22 = False,
x0 = False,
x10 = False,
x12 = False,
x3 = False,
x14 = False,
x21 = False,
x2 = False,
x1 = False,
x17 = False,
x5 = False,
x13 = False,
x20 = False,
x4 = False,
x9 = False,
x15 = False,
x19 = False,
x18 = False,
x6 = False,
x7 = False,
x8 = False,
x16 = False]
State  3
[x11 = True,
x22 = False,
x0 = True,
x10 = False,
x12 = True,
x3 = False,
x14 = False,
x21 = False,
x2 = False,
x1 = False,
x17 = False,
x5 = True,
x13 = False,
x20 = True,
x4 = False,
x9 = False,
x15 = False,
x19 = False,
x18 = True,
x6 = True,
x7 = False,
x8 = False,
x16 = False]
Number of States= 3

在线here

运行此示例

答案 4 :(得分:0)

其他例子:拟南芥花形态发生控制的布尔网络模型

enter image description here

代码:

def add_constraints(s, model):
X = BoolVector('x', 15)
s.add(Or(And(X[7],X[0],X[14]),And(Not(X[8]),Not(X[12])),And(X[7],Not(X[11])))== X[0])
s.add(Or(And(X[0],X[13],X[14],X[1]),And(X[5],X[13],X[14],X[1]),And(X[7],X[2])) == X[1])
s.add(X[2] == X[2])
s.add(And(Not(X[5]),Not(X[12])) == X[3])
s.add(Not(X[6]) == X[4])
s.add(Or(And(Not(X[0]),Not(X[12])),And(X[7],Not(X[0])),And(X[4],Not(X[0]))) == X[5])
s.add(Not(X[7]) == X[6])
s.add(Or(Not(X[12]),Not(X[6]))== X[7])
s.add(Not(X[12])== X[8])
s.add(Or(And(X[9],Not(X[14])),And(X[9],Not(X[0]))) == X[9])
s.add(True == X[10])
s.add(True == X[11])
s.add(And(Not(X[5]),X[6],Not(X[7])) == X[12])
       s.add(Or(And(X[5],X[13],X[14],X[1]),And(X[0],X[13],X[14],X[1]),And(X[7],X[0]),And(X[7],X[1]))==X[13])
s.add(X[7]== X[14])





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))

return s


s = Solver()
i = 0
add_constraints(s, [])
while s.check() == sat:
print "========================================================================="  

print "State ", (i + 1), ":"
for c in s.model():
    if is_true((s.model())[c]):
        print c ,"=", 1
    else:
        print c, "=", 0
i = i + 1
add_constraints(s, s.model())
print "========================================================================="

print "Number of States=", (i)

输出:

Number of States= 14

在第here

上运行此示例