用Prolog求解CNF
在学习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
(!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.