Prolog中符合逻辑的“不”是什么?

我面对的问题有点微不足道。 我想在Prolog中使用逻辑,但似乎not/1不是我想要的东西:

 course(ai). course(pl). course(os). have(X,Y) :- course(X),course(Y),not(X = Y). 

我查询:

 have(X,Y), write(XY), nl , fail. 

而我没有得到我想要的结果:(

代替not(X = Y)你需要写成\+ X = YX \= Y 但是考虑用dif(X,Y)来代替。 在B,SWI,YAP,SICStus中存在dif/2 。 要看到不同之处:

 ?- X = b, dif(a, X). X = b. ?- X = b, \+ a = X. X = b. 

所以到现在一切似乎都很好。 但是,如果我们简单地交换两个目标的顺序呢?

 ?- \+ a = X, X = b. false. ?- dif(a, X), X = b. X = b. 

(\+)/1现在给我们一个不同的结果,因为对于a = X有一个答案,目标\+ a = X将会失败。

(\+)/1因此不是否定的,但意味着在这个时间点不可certificate

ISO Prolog也可以安全地近似 dif/2

在SWI-Prolog和GNU Prolog中,都应该起作用:

 have(X, Y) :- course(X), course(Y), X \= Y. 

在SWI-Prolog中,你也可以使用dif/2 ,这可以更方便,因为你可以在谓词的前面使用它:

 have(X, Y) :- dif(X, Y), course(X), course(Y). 

作为上面用户“假”的答案的补充,即

“代替不(X = Y)你需要写\ + X = Y,”

这可能给人的印象是:

一个。 “不”和“\ +”是不同的东西

湾 \ \将工作,而不会,错,不。

我的理解是,“不”和“\ +”是等价的,但是在现代Prolog程序中,\ +是首选,因为它传达了一种更直观的感觉。 具体而言,“不”可能暗示对不谨慎的编码者“不正确”,“\ +”表示“不可certificate”,这更接近该操作实际所说的真相。 在Prolog中,“不”是“否定为失败”的一个例子,但是人们认为“+”会让程序员更清楚地知道在任何给定的规则中究竟是什么。 所以你可以使用“不”(大多数PL实现为了向后兼容),但要成为一个惯用的现代PL程序员,你可能应该更喜欢使用\ +。

就像你说的,OP,这是微不足道的。

尝试

 course(ai). course(pl). course(os). have(X,Y) :- course(X), course(Y), X \== Y). 

这应该修复你的谓词。

尽pipe在math上expression一步,但是你可能正在寻找(n C 2)的解,而不是你的谓词所提供的(n P 2) – 组合而不是排列,selectselect而不是select的select。 这是我的想法。

如果这是你想要的,我会build议你试试

 course(ai). course(pl). course(os). have(X,Y) :- course(X), course(Y), X @< Y). 

这将防止重复颠倒的结果。

@<表示primefaces小于。 <用于整数, @<用于primefaces。