我刚开始使用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解算器==4.8.0.0.post1