Prolog,跳过根据规则向列表添加元素

时间:2016-02-27 15:14:00

标签: list recursion filter prolog

我有一些Prolog代码,如果X和Y的乘积大于某个值,我希望能够跳过向结果列表添加元素。知道怎么做这个吗?

e.g。

if Product > 10

到目前为止我的代码

make_quads(_,[],[]).
make_quads(X,[Y|TAIL],[[X,Y,Sum,Product]|Result]):-
    make_quads(X,TAIL,Result),
    Product is X * Y,
    Product > 2,
    Sum is X + Y.

该函数调用如下:

?- make_quads(5, [1,2,3,4,5,6], X).

将提供以下输出:

X = [[5, 1, 6, 5], [5, 2, 7, 10], [5, 3, 8, 15], [5, 4, 9, 20], [5, 5, 10, 25], [5, 6, 11|...]]

我尝试了以下几行,但是一旦调用函数,SWI-Prolog就会返回false

make_quads(_,[],[]).
make_quads(X,[Y|TAIL],[[X,Y,Sum,Product]|Result]):-
    make_quads(X,TAIL,Result),
    Product is X * Y,
    Product > 20, % I need to skip here
    % Else continue running
    Sum is X + Y.

1 个答案:

答案 0 :(得分:2)

您已经观察到谓词失败的原因是因为它需要成功(而不是失败)Product =< 20,但只是不保留值。就目前而言,一旦你的谓词在Product > 20上失败,整个谓词就会失败,因为它缺少这样一个句子

你的主要条款需要分为两种情况。执行此操作的简单方法是为Product =< 20的情况添加另一个子句。此外,您可以在此处使用尾递归,这可以通过一些Prolog解释器进行优化。在设置值之前无需递归:

make_quads(_, [], []).
make_quads(X, [Y|TAIL], [[X,Y,Sum,Product] | Result]):-
    Product is X * Y,
    Product > 20,
    Sum is X + Y,
    make_quads(X, TAIL, Result).
make_quads(X, [Y|TAIL], Result):-
    Product is X * Y,
    Product =< 20,
    make_quads(X, TAIL, Result).

您也可以使用Prolog ->运算符,效率更高一些:

make_quads(_, [], []).
make_quads(X, [Y|TAIL], Result):-
    Product is X * Y,
    (   Product > 20
    ->  Sum is X + Y,                   % Do this if Product > 20
        Result = [[X,Y,Sum,Product]|R]
    ;   Result = R                      % Do this if Product =< 20
    ),
    make_quads(X, TAIL, R).