有四个篮子,每个篮子都有独特的颜色。我编写了一个prolog程序,根据一些事实和规则来判断颜色顺序。这是.pl文件:
iright(L, R, [L | [R | _]]).
iright(L, R, [_ | Rest]) :- iright(L, R, Rest).
nextto(L, R, List) :- iright(L, R, List).
nextto(L, R, List) :- iright(R, L, List).
myprogram(Data) :- =(Data, [_,red,_,_]),
\+nextto(red,blue,Data), % blue is not next to red
iright(red,green,Data), %green is right to red
member(red,Data),
member(blue,Data),
member(green,Data),
member(yellow,Data).iright和nextto谓词是正确的。我的查询是myprogram(Data),我希望结果应该是
Data = [yellow,red, green, blue]?
yes但实际上提示符显示
| ?- myprogram(Data).
no我知道问题是否定,但我不知道如何和为什么。请帮帮忙。
当我使用trace.时
1 1 Call: myprogram(_16) ?
2 2 Call: \+nextto(red,blue,[_46,red,_50,_52]) ?
3 3 Call: nextto(red,blue,[_46,red,_50,_52]) ?
4 4 Call: iright(red,blue,[_46,red,_50,_52]) ?
5 5 Call: iright(red,blue,[red,_50,_52]) ?
5 5 Exit: iright(red,blue,[red,blue,_52]) ?
4 4 Exit: iright(red,blue,[_46,red,blue,_52]) ?
3 3 Exit: nextto(red,blue,[_46,red,blue,_52]) ?
2 2 Fail: \+nextto(red,blue,[_46,red,_50,_52]) ?
1 1 Fail: myprogram(_16) ?
(2 ms) no发布于 2012-11-21 08:43:48
如果您将\+nextto(red, blue, Data)移到myprogram的最后一行,它将正常工作。
这有点不直观,但您需要考虑一下Prolog如何计算表达式&否定的真正含义。否定的意思是“这不可能是真的”,而不是“对于一组特定的值不可能是真的”。如果你把你的程序简化为:
myprogram(Data) :-
=(Data, [_,red,_,_]),
\+nextto(red,blue,Data).你仍然会得到一个No.。这是因为,根据您所声明的,Data 可以是 [_, red, blue, _] -您可以看到Exit: iright(red,blue,[red,blue,_52])做出了这个决定。Prolog试图回溯,但它没有其他方法可以尝试-您还没有将任何_s限制为具有特定值。
如果你把所有的nextto,member & iright语句放在被否定的语句之前,那么当它到达被否定的表达式时,有多种可能的解决方案(好吧,有两种)可供尝试:Data = [blue,red,green,yellow]和Data = [yellow,red,green,blue]。在这一点上,当它看到否定时,它会“丢弃”红色旁边是蓝色的“分支”,但它能够回溯,并且具有使否定为真的可能的世界状态。这就是说:
myprogram(Data) :-
=(Data, [_,red,_,_]),
iright(red,green,Data),
member(red,Data),
member(blue,Data),
member(green,Data),
member(yellow,Data),
\+nextto(red,blue,Data)....gives你想要的结果。
在Prolog中,DR- negation (以及切分)比你一开始认为的要强大得多。在使用它们之前,请确保你已经弄清楚了所有其他的事情。
https://stackoverflow.com/questions/13484407
复制相似问题