使用Fixpoint(数据记录引擎)添加约束的正确方法,以避免“否定否定”错误

时间:2019-04-25 14:30:43

标签: z3 z3py

我正在尝试在{3}中使用Fixedpoint和数据记录(使用Python界面),因为我正在尝试在个人项目中复制Alloy的某些功能。

我写了一个非常简单的“父母和祖先”示例:

s = Fixedpoint()
s.set(engine="datalog")

P = FiniteDomainSort("Person", 16)

X = Var(0, P)
Y = Var(1, P)
Z = Var(2, P)

# parent(X, Y)  "X is parent of Y"
parent = Function("parent", P, P, BoolSort())

# ancestor(X, Y)  "X is ancestor of Y"
ancestor = Function("ancestor", P, P, BoolSort())

s.register_relation(parent, ancestor)

# x is ancestor of y follows from x being parent of y
s.rule(
    ancestor(X, Y),
    parent(X, Y))

# x is ancestor of y follows from x being parent of z and z being ancestor of y
s.rule(
    ancestor(X, Y),
    And(
        parent(X, Z),
        ancestor(Z, Y)))

# facts
alice = FiniteDomainVal(0, P)
bob = FiniteDomainVal(1, P)
mary = FiniteDomainVal(2, P)
luke = FiniteDomainVal(4, P)
eve = FiniteDomainVal(3, P)

s.fact(parent(alice, bob))
s.fact(parent(bob, mary))
s.fact(parent(mary, luke))

到目前为止,除非我添加诸如parent(bob, bob)And(parent(alice, bob), parent(bob, alice))之类的“不合理”事实,否则它仍然可以正常工作。当陈述无效事实时,如何添加规则使整个模型不满意?

我的一些首次尝试涉及添加带有否定词的规则,从而产生“分层否定”错误。我还尝试过用assert_exprs添加公理,但是在查询时似乎没有考虑到它们(并且没有check模型方法可用。)

我当前的解决方案涉及添加一个“无效”关系,我可以检查该关系是否为空:

invalid = Function("invalid", P, BoolSort())
s.register_relation(invalid)

s.rule(
    invalid(X),
    And(
        parent(X, Y),
        parent(Y, X)))

然后,我知道我的模型在s.query(invalid(X)) == unsat时是“正确的”。实际上,添加事实parent(bob, bob)可确保invalid(X)处于坐姿。

有更好的方法吗?

谢谢!

0 个答案:

没有答案