编写谓词

Writing a Predicate

我是 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). 的内容时我的程序崩溃了 我不明白如何过滤掉我的结果不想让程序正常 运行。

我不明白你为什么定义谓词

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尝试查询两个订单,如果都失败,则谓词结束。

在序言中您必须了解的是,所有未指定为真的都是假的。这就是他们所说的 最小世界假设 。所以如果你没有指定 goodveggies(broc,tomato) 并且它不能由某些谓词导出,程序将 return 为假。如果您不想使用可变顺序,列出事实就可以了:

goodveggies(broc,spinach).
goodveggies(broc,artichoke).