Recursion Prolog谓词生成列表

Recursion Prolog谓词生成列表,recursion,prolog,Recursion,Prolog,定义Prolog谓词makelist/3,使makelist(开始、结束、列表)在以下情况下为true 列表是从整数开始到整数结束的所有整数的列表。例如: makelist(3, 7, [3, 4, 5, 6, 7]) should be true. 我不明白为什么我的代码不起作用 makelist(H, L, _) :- L is H+1. makelist(H, L, List) :- append([], [H], List), H1 is H+1. makelist(H

定义Prolog谓词
makelist/3
,使
makelist(开始、结束、列表)
在以下情况下为true 列表是从整数
开始
到整数
结束
的所有整数的列表。例如:

makelist(3, 7, [3, 4, 5, 6, 7]) should be true.
我不明白为什么我的代码不起作用

makelist(H, L, _) :-
    L is H+1.
makelist(H, L, List) :-
    append([], [H], List), H1 is H+1.
makelist(H1, L, List) :-
    append(List, [H1], List1), last(List1, R),
    R \= L+1, makelist(N, L, List1), N is H1+1.

您可以简化代码,让我们使用谓词并检查您真正需要做的事情:

% makelist(X,Y,L)
由于递归调用将第一个参数增加1,我们将其称为X,那么基本情况是X与Y相同:

makelist(X,X,[X]) .
递归调用:当X小于Y时,需要增加X并将值添加到列表中:

makelist(X,Y,[X|L]) :-  X < Y ,
            X1 is X + 1 ,
            makelist(X1, Y, L).
makelist(X,Y,[X | L]):-X
如果查询
makelist(3,4[x,y,z]),您的第一个子句将立即成功。
例如,因为
4是3+1
将成功<代码>[x,y,z]可以是任何列表,它会成功。在您的第二个子句中,
H1
的计算结果为
H+1
,但从来不使用
H1
。你的第三个从句使用了
last/2
。在何处以及如何定义?@lowerer
last/2
在SWI-Prolog中预定义。我不知道either@Shevliaskovic谢谢我总是发现GNU中没有的新SWI谓词。:)@user3612140-考虑一下简单(基本)案例。它看起来像什么?我建议在这种情况下,
H
L
是相同的。所以您的基本大小写谓词可能是,
makelist(H,H,?)
(什么样的
)。然后考虑如何从一般情况递归到基本情况。
last/2
谓词是SWI Prolog中的库谓词,而不是内置谓词。它在
列表
模块中定义,默认情况下,当找到对其谓词之一的调用时,该模块将自动加载。