我是Prolog的新手,我正在尝试编写谓词goodveggies(X,Y)
,以便代码按以下方式运行:
?- goodveggies(broc,spinach).
true.
?- goodveggies(X,artichoke).
X = broc
我尝试过的事情:
% Define the facts:
goodveggies(broc,spinach).
goodveggies(broc,artichoke).
% Now make the predicate.
goodveggies(X,Y) :- goodveggies(X,Y).
我的程序运行正常,但我遇到的问题是当我输入类似的内容时,我的程序崩溃了,goodveggies(broc, tomato).
我不明白如何过滤掉我不喜欢的结果想要让程序正常运行。
答案 0 :(得分:1)
我不明白为什么要定义谓词
goodveggies(X,Y) :- goodveggies(X,Y).
这根本没有意义,因为如果它是真的,那么goodveggies (X,Y)
似乎是真的。此外,如果您要查询goodveggies(broc, tomato)
,它将具有以下无限执行(添加备注):
goodveggies(broc, tomato) :-
goodveggies(broc, spinach); FAIL!
goodveggies(broc,artichoke); FAIL!
goodveggies(broc, tomato) :-
goodveggies(broc, spinach); FAIL!
goodveggies(broc,artichoke); FAIL!
goodveggies(broc, tomato) :-
goodveggies(broc, spinach); FAIL!
goodveggies(broc,artichoke); FAIL!
goodveggies(broc, tomato) :-
...
所以你一直在查询相同的事实。
您可能希望能够交换值出现的顺序,因此:
goodveggies(X,Y) :- goodveggies(Y,X).
现在这也不会奏效,因为它会尝试:
goodveggies(broc,tomato) :-
goodveggies(tomato,broc) :-
goodveggies(broc,tomato) :-
goodveggies(tomato,broc) :-
...
但是,您可以通过定义两个谓词来解决此问题:
gv(broc,spinach).
gv(broc,artichoke).
goodveggies(X,Y) :-
gv(X,Y).
goodveggies(X,Y) :-
gv(Y,X).
第一个谓词gv/2
定义了蔬菜的良好组合,第二个goodveggies/2
尝试查询两个订单,如果它们都失败,则谓词结束。
您在prolog中必须了解的是,未指定为true 的所有内容均为false。这就是他们所谓的最小世界假设。因此,如果您没有指定goodveggies(broc,tomato)
并且它不能通过某个谓词派生,则程序将返回false。如果您不想要变量订单,列出事实就可以了:
goodveggies(broc,spinach).
goodveggies(broc,artichoke).