0

我有这个功能

sublist(_,[_],_) :-
    !.
sublist(X,[Y|T],Z) :-
    R is X - Y,
    sublist(X,T,[R|Z]).

一个示例调用是sublist(2,[1,2,3],Z). 在执行结束时它只给我“是”,但我想看看 Z 的内容。

我知道这很简单,因为我有其他指令可以做类似的事情,但是这个不起作用。

4

2 回答 2

3

我还将假设 sublist/3 应该从列表中的所有项目中减去一个数字。

您没有得到 Z 的任何结果的原因是因为您在进入递归的过程中构建了列表。这意味着当停止谓词成功时,Prolog 会退出递归,并且 Z 再次变得未实例化。

Z is ?
    |
    Z is [-1]
        |
        Z is [-1, 0]
            |
            Z is [-1, 0, 1]
            |
        Z is [-1, 0]
        |
    Z is [-1]
    |
Z is ?

尝试先进入递归并在退出时构建您的列表。也许是这样的:

subtract_list(_, [], []).

subtract_list(Number, [Head|Tail], [Subtracted|Result]):-
    subtract_list(Number, Tail, Result),
    Subtracted is Head - Number.

我们改变的只是递归谓词中规则的顺序和停止条件的条款。现在它递归直到它到达一个空列表,此时它也用一个空列表实例化结果变量。然后它会在这样做的同时将值添加到列表中。

?- subtract_list(1,[4,3,2],Z).
Z = [3, 2, 1] 

希望这可以帮助。汤姆

于 2009-04-04T12:47:05.247 回答
1

您并没有真正指定sublist/3应该做什么,但也许您的意思是:

sublist(_, [], []) :- !.

sublist(X, [Y | T], [R | Z]) :-
    R is X - Y,
    sublist(X, T, Z).

使用示例:

?- sublist(2, [1, 2, 3], Z).
Z = [1, 0, -1].

顺便说一句,如果您不想自己遍历列表,那么您可以使用maplist/3SWI-Prolog 提供的列表。首先定义您想要的计算:

my_calculation(X, Y, Z) :-
    Z is X - Y.

然后调用maplist/3

?- maplist(my_calculation(2), [1, 2, 3], Z).
Z = [1, 0, -1].
于 2008-12-18T19:56:57.897 回答