0

我需要在下面写规则:

编写谓词 take(L,N,L1) 的规则,如果列表 L1 包含列表 L 的前 N ​​个元素,则以相同的顺序成功。以下查询显示了使用此谓词的示例:

?- take([5,1,2,7], 3, L1).
L1 = [5,1,2]
?- take([5,1,2,7], 10, L1).
L1 = [5,1,2,7]

我的想法是随时删除两个列表的第一个数字,直到 L1 为空。我也在想我可以使用 car([X|_], X) 每次删除最后一个数字,直到第一个列表==第二个列表。我已经写了长度(L,Len),但我不知道下一步该怎么做......

我的代码是:

take(L,X,[]).(I know it miss something, but I don't know how to do...)
take(H|L,N,H|L1):- take(L,X,L1), N is X-1.

==========================更新======================== ==========================谢谢1638891!现在,代码是

    take(L,0,[]).
    take([H|L],N,[H|L1]):- take(L,X,L1), N is X+1.

但它在第二种情况下不起作用,即

   ?- take([5,1,2,7], 10, L1).
   L1 = [5,1,2,7]

我试图添加

    take([],X,[])->!.

但它会弹出“错误:is/2:参数没有充分实例化”。

4

2 回答 2

0

你实际上想写 X 是 N - 1。

take(L,0,[]).
take([H|L],N,[H|L1]):- take(L,X,L1), X is N-1.

作为一般规则,请尝试大声朗读您的规则。您编写的第一条规则是“空列表是 L 中前 X 个元素的列表”。但它应该是“空列表是 L 中前 0 个元素的列表”作为基本情况。

于 2012-12-03T08:52:42.393 回答
0

@user1638891 忘记交换减法,并在请求的元素多于可用元素时覆盖这种情况:

take(_,0,[]).
take([],_,[]).
take([H|L],N,[H|L1]) :- N > 0, X is N-1, take(L,X,L1).
于 2012-12-03T12:52:18.217 回答