Z3答案不满足约束

时间:2019-02-03 23:22:51

标签: z3 z3py

我刚开始使用Z3,但给了它一个玩具问题。这个想法适用于(a,b,c)的所有分配,(fa(b,c)== a,fb(a,c)== b,fc(a,b)== c)中的至少一个必须为真。

模型报告

[fc = [else -> And(Not(Var(1)), Var(0))],
  fa = [else -> And(Var(1), Var(0))],
  fb = [else -> False]]

似乎不满足(a = False,b = True,c = True)情况的约束,如下表所示。

我在做什么错,如何获得满足约束条件的解决方案,如第二张表中所示的规则?

import pandas as pd
from z3 import Bools, Function, BoolSort, Solver, ForAll, Or

a, b, c = Bools("a b c")
fa = Function("fa", BoolSort(), BoolSort(), BoolSort())
fb = Function("fb", BoolSort(), BoolSort(), BoolSort())
fc = Function("fc", BoolSort(), BoolSort(), BoolSort())

s = Solver()
s.add(ForAll([a, b, c], Or(fa(b, c) == a, fb(a, c) == b, fc(a, b) == c)))


def tabulate(fa, fb, fc):
    mi = pd.MultiIndex.from_product(
        [[False, True] for _ in range(3)], names=["a", "b", "c"]
    )
    df = pd.DataFrame(index=mi).reset_index()
    return (
        df.assign(fa=fa, fb=fb, fc=fc)
        .assign(
            fb_correct=lambda x: x.fb == x.b,
            fa_correct=lambda x: x.fa == x.a,
            fc_correct=lambda x: x.fc == x.c,
        )
        .assign(any_correct=lambda x: x.fb_correct | x.fa_correct | x.fc_correct)
        .astype(int)
    )


print(s.check())
print(s.model())

# sat
# [fc = [else -> And(Not(Var(1)), Var(0))],
#  fa = [else -> And(Var(1), Var(0))],
#  fb = [else -> False]]

print(tabulate(fb=False, fa=lambda x: x.b & x.c, fc=lambda x: x.a & ~x.b))

#    a  b  c  fa  fb  fc  fb_correct  fa_correct  fc_correct  any_correct
# 0  0  0  0   0   0   0           1           1           1            1
# 1  0  0  1   0   0   0           1           1           0            1
# 2  0  1  0   0   0   0           0           1           1            1
# 3  0  1  1   1   0   0           0           0           0            0
# 4  1  0  0   0   0   1           1           0           0            1
# 5  1  0  1   0   0   1           1           0           1            1
# 6  1  1  0   0   0   0           0           0           1            1
# 7  1  1  1   1   0   0           0           1           0            1


# Correct answer:
print(
    tabulate(fb=lambda x: ~x.a | x.b, fa=lambda x: x.b & x.c, fc=lambda x: x.a & ~x.b)
)

#    a  b  c  fa  fb  fc  fb_correct  fa_correct  fc_correct  any_correct
# 0  0  0  0   0   1   0           0           1           1            1
# 1  0  0  1   0   1   0           0           1           0            1
# 2  0  1  0   0   1   0           1           1           1            1
# 3  0  1  1   1   1   0           1           0           0            1
# 4  1  0  0   0   0   1           1           0           0            1
# 5  1  0  1   0   0   1           1           0           1            1
# 6  1  1  0   0   1   0           1           0           1            1
# 7  1  1  1   1   1   0           1           1           0            1

版本:z3-solver == 4.8.0.0.post1

1 个答案:

答案 0 :(得分:1)

我无法复制它。运行程序时,我得到:

[fc = [else -> And(Var(0), Var(1))],
 fa = [else -> And(Var(0), Not(Var(1)))],
 fb = [else -> False]]

这似乎是正确的模型。请注意,这与您所得到的有所不同,因为在您的情况下似乎可以交换fcfa

这很可能是已经修复的错误;我正在使用来自github来源的最新编译的z3。您可以升级z3安装并查看问题是否消失吗?