用Prolog求解CNF

用Prolog求解CNF,prolog,conjunctive-normal-form,clpb,Prolog,Conjunctive Normal Form,Clpb,在学习Prolog的过程中,我试图编写一个程序来解决CNF问题(性能不是问题),因此我最终得到了以下代码来解决(!x|y|124;!z)&&(x|124;!y|124; z)&&(x|y|z)&(!x|124; 124;!y|z): 有没有更简单、更直接的方法来使用这种声明性语言解决CNF问题?在Prolog中查找“精益定理证明器”(如or)以获得简单、简短的定理证明器。这些都是为了尽可能地利用Prolog特性而设计的。尽管像这样的验证程序使用一阶逻辑,但CNF是其中的一个子集。对于Prolog

在学习Prolog的过程中,我试图编写一个程序来解决CNF问题(性能不是问题),因此我最终得到了以下代码来解决
(!x|y|124;!z)&&(x|124;!y|124; z)&&(x|y|z)&(!x|124; 124;!y|z)


有没有更简单、更直接的方法来使用这种声明性语言解决CNF问题?

在Prolog中查找“精益定理证明器”(如or)以获得简单、简短的定理证明器。这些都是为了尽可能地利用Prolog特性而设计的。尽管像这样的验证程序使用一阶逻辑,但CNF是其中的一个子集。对于Prolog也有专用的SAT求解器,如

< P> >考虑使用内置谓词<代码> true /0 < /COD>和<代码> false /0 < /COD>直接,并使用ToPrVIEW显示结果(独立地,而不是几个后续的<代码>写/ 1 < /代码>调用,考虑使用<代码>格式/ 2 < /代码>):

例如:

?- cnf(X, Y, Z).
X = true,
Y = true,
Z = true .
编辑:正如@repeat所解释的那样,还需要认真研究CLP(B):布尔约束求解

使用CLP(B),您可以将上述整个程序编写为:

:- use_module(library(clpb)).

cnf(X, Y, Z) :-
        sat(~X + Y + ~Z),
        sat(X + ~Y + Z),
        sat(X + Y + Z),
        sat(~X + ~Y + Z).
更多信息请参见@repeat的答案。

使用

:- use_module(library(clpb)). 还没有具体的解决方案。。。但是一个比我们开始用的术语简单得多的残留物

要获得具体的真值,请使用:

?-(X=\=X*Y#Z),([X,Y,Z])。 X=0,Y=0,Z=1 ; X=0,Y=1,Z=1 ; X=1,Y=0,Z=0 ; X=1,Y=1,Z=1。
我使用的是Gnu Prolog 1.3,当我运行代码时(在定义maplist谓词之后),我得到一些异常。它是否在其他编译器上运行?如果您的系统尚不支持false/0,请添加规则“false:-fail.”。GNU Prolog(1.4)的最新开发版本、YAP和SWI都有它,等等。OP在我的回答后更改了问题,这如实地翻译了原始问题;-)
:- use_module(library(clpb)).

cnf(X, Y, Z) :-
        sat(~X + Y + ~Z),
        sat(X + ~Y + Z),
        sat(X + Y + Z),
        sat(~X + ~Y + Z).
:- use_module(library(clpb)). % OP: "(!x||y||!z) && (x||!y||z) && (x||y||z) && (!x||!y||z)" ?- sat((~X + Y + ~Z)*(X + ~Y + Z)*(X + Y + Z)*(~X + ~Y + Z)). sat(X=\=X*Y#Z). ?- sat(X=\=X*Y#Z), labeling([X,Y,Z]). X = 0, Y = 0, Z = 1 ; X = 0, Y = 1, Z = 1 ; X = 1, Y = 0, Z = 0 ; X = 1, Y = 1, Z = 1.