C++ 用Z3证明分辨定理

C++ 用Z3证明分辨定理,c++,z3,C++,Z3,我是Z3新手,但之前有一些使用Prolog的经验 我已经解决了下面的“难题”,即用Prolog证明女孩是女巫,但在Z3(C++或Python)中如何实现它,我感到茫然: 我需要为断言声明Function()吗 BURNS(x)/\WOMAN(x)和WOMAN(GIRL) 排序的含义是什么?对于所有的x,ISMADEOFWOOD(x)=>BURNS(x) 任何提示都值得欣赏应该指出的是,SMT解算器(即Z3)通常不擅长使用量词进行推理,但这种特殊情况非常简单,可以轻松处理。(这很容易,因为你所有

我是Z3新手,但之前有一些使用Prolog的经验

我已经解决了下面的“难题”,即用Prolog证明女孩是女巫,但在Z3(C++或Python)中如何实现它,我感到茫然:

我需要为断言声明Function()吗
BURNS(x)/\WOMAN(x)
WOMAN(GIRL)
排序的含义是什么?对于所有的x,ISMADEOFWOOD(x)=>BURNS(x)


任何提示都值得欣赏

应该指出的是,SMT解算器(即Z3)通常不擅长使用量词进行推理,但这种特殊情况非常简单,可以轻松处理。(这很容易,因为你所有的都是未解释的排序和布尔值;没有整数、实数、数据类型等使逻辑复杂化。)此外,当你使用SMT解算器时,与Prolog的演绎策略相比,有一些建模差异,所以建模会有点不同

关键的一点是Prolog使用了所谓的封闭世界假设观点。也就是说,如果它不能显示暗示,它将决定它不是暗示的。SMT解决方案不会这样做:它将证明其含义;但是,如果您查询一个没有适当约束的变量(即,如果根据断言它可以是
True
False
),那么它可以自由选择任何解释。因此,建模必须考虑到这一点

这对当前的问题意味着什么?我们必须证明这些陈述暗示这个女孩是个女巫。如果他们没有,我们就不知道她是不是。为此,我们断言我们想要的结论是否定的,并检查结果系统是否不可满足。如果是这样,那么我们可以得出结论,我们的结论一定是有效的。如果结果是令人满意的,那么我们有一个反例模型,可以进一步研究。在这种情况下,这意味着没有足够的证据证明这个女孩是女巫。(请注意,添加对我们要证明的结论的否定是非常典型的解析证明,我们在这里遵循相同的策略。)

给出了这一切,下面我将如何使用Python API建模它,您应该能够相对容易地将其转换为C++(或任何其他具有适当绑定的语言)。这些条款几乎是字面意思:

从z3导入*
Thing=DeclareSort(‘Thing’)
女孩=常量(“女孩”,事物)
鸭子=常数(“鸭子”,东西)
BURNS=函数('BURNS',Thing,BoolSort())
FLOATS=函数('FLOATS',Thing,BoolSort())
WOMAN=函数('WOMAN',Thing,BoolSort())
WITCH=函数('WITCH',Thing,BoolSort())
SAMEWEIGHT=函数('SAMEWEIGHT',Thing,Thing,BoolSort())
ISMADEOFWOOD=函数('ISMADEOFWOOD',Thing,BoolSort())
s=解算器()
x=常数('x',事物)
y=常数('y',事物)
s、 添加(ForAll([x],暗指(和(BURNS(x),WOMAN(x)),WITCH(x)))
s、 加(女(女))
s、 添加(对于所有([x],意味着(ISMADEOFWOOD(x),BURNS(x)))
s、 add(ForAll([x],暗指(FLOATS(x),ISMADEOFWOOD(x)))
s、 添加(浮动(鸭子))
s、 加法(ForAll([x,y]),暗指(和(FLOATS(x),SAMEWEIGHT(x,y)),FLOATS(y)))
s、 添加(SAMEWEIGHT(鸭子、女孩))
#为了证明那个女孩是个女巫,我们断言否定,
#并检查是否不符合要求。
s、 添加(不是(女巫(女孩)))
res=s.check()
如果res==sat:
打印(“不,这并不意味着她是个女巫!”
elif res==unsat:
打印(“是的,她是个女巫!”)
其他:
打印(“嗯,解算器说:”,res)
当我运行此程序时,我得到:

Yes, she is a witch!
对她来说太糟糕了

你可以通过注释一些断言进行实验,你会看到z3会说系统是
sat
,也就是说,它不能断定女孩是女巫。然后,您可以详细查看模型本身,以了解分配是什么


您可以通读一遍,了解如何将基本Python API用于未解释的排序、量词和基本建模。如果您有具体问题,请随时提问。

感谢您的详细解释!您的解决方案中的所有内容都有效。我在原来的帖子后面又附加了几个问题。也许我应该将这些单独发布到SoF?如果问题是自包含的并且只解决一个问题,堆栈溢出效果最好。请分别提问,这样其他人也会有机会看到并回答。好了:我真的很想看看你对另一个问题的看法。