写一个谓词

时间:2015-01-27 23:35:56

标签: prolog

我是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).我不明白如何过滤掉我不喜欢的结果想要让程序正常运行。

1 个答案:

答案 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).