我正在尝试在{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)
处于坐姿。
有更好的方法吗?
谢谢!