目前,我在七周内练习七种语言的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
失败?
答案 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中你无法避免理解操作语义......