当我在开始时进行相等比较时,为什么prolog不会给出所有结果?

时间:2015-02-26 08:32:36

标签: prolog

目前,我在七周内练习七种语言的Prolog章节。我试图更改着色示例,以便不记下每个有效的颜色组合。

different(red, green).
different(green, red).
different(red, blue).
different(blue, red).
different(blue, green).
different(green, blue).

coloring(A, M, G, T, F) :-
    different(M, T),
    different(M, A),
    different(A, T),
    different(A, M),
    different(A, G),
    different(A, F),
    different(G, F),
    different(G, T).

我更改了文件以使其功能不同:

color(red).
color(blue).
color(green).

different(X, Y) :- color(X), color(Y), \+(X=Y).
different_fail(X, Y) :- \+(X=Y), color(X), color(Y).

coloring(A, M, G, T, F) :-
    different(M, T),
    different(M, A),
    different(A, T),
    different(A, M),
    different(A, G),
    different(A, F),
    different(G, F),
    different(G, T).

我不能得到的是different为我提供了不同颜色的所有组合,但different_fail只检查它们是否真的不同。

GNU Prolog 1.4.5 (32 bits)
Compiled Feb 23 2015, 08:36:31 with gcc
By Daniel Diaz
Copyright (C) 1999-2015 Daniel Diaz
| ?- ['color'].             
compiling /home/rudi/7langs/prolog/color.pl for byte code...
/home/rudi/7langs/prolog/color.pl compiled, 17 lines read - 2206 bytes written, 7 ms
| ?- different(red, red).   

no
| ?- different(red, blue).

yes
| ?- different_fail(red, red). 

no
| ?- different_fail(red, blue).

到此为止,一切都按预期进行。

yes
| ?- different(red, A).        

A = blue ? ;

A = green

yes
| ?- different_fail(red, A).

no

但在这里,我希望different_fail能够得到与different完全相同的结果。

这些功能有什么不同,导致different_fail失败?

2 个答案:

答案 0 :(得分:1)

要以声明方式表达两个术语不同,请使用dif/2约束,该约束可在SICStus Prolog,SWI-Prolog,YAP和其他几个中使用。

如果你这样写different_colors/2

different_colors(X, Y) :- dif(X,Y), color(X), color(Y).

然后一切都会按照您的预期完成,无论您将目标放在哪个顺序。

目前失败的原因是\+/1仅表示目前无法证明。在陈述性意义上,这不是真正的否定。因此,我们有:

?- \+ X = Y, X = a, Y = b.
false.

但如果我们只是通过连词的交换来交换目标:

?- X = a, Y = b, \+ X = Y.
X = a,
Y = b.

相比之下,dif/2在两种情况下都能正常工作,我强烈建议您使用它:

?- dif(X, Y), X = a, Y = b.
X = a,
Y = b.

?- X = a, Y = b, dif(X, Y).
X = a,
Y = b.

答案 1 :(得分:0)

根据定义,(=)/2表示统一,而不是相等,变量可以与任何内容统一。

然后,当你将一个未绑定的变量传递给different_fail / 2时,它的第一个目标将失败,因为统一实际上已经执行,然后由于否定而立即撤消...

我不能完全同意答案......我认为在Prolog中你无法避免理解操作语义......