List 列表长度,插入元素

List 列表长度,插入元素,list,prolog,List,Prolog,我正试图用Prolog编写一个程序,它将把一个元素插入到某个位置,例如 ?- ins(a, [1,2,3,4,5], 3, X). X = [1,2,a,3,4,5]. 我有以下代码: ins(X,[H|T],P,OUT) :- length([T3],P), concatenate(X,[H],T), ins(...). 问题是它从后面在给定索引中插入元素X(我甚至知道问题在哪里->长度([T3],p),这显然是列表从后面开始的长度,而不是从开头开始的长度)。我试着记住

我正试图用Prolog编写一个程序,它将把一个元素插入到某个位置,例如

?- ins(a, [1,2,3,4,5], 3, X).
X = [1,2,a,3,4,5].
我有以下代码:

ins(X,[H|T],P,OUT) :-
   length([T3],P),
   concatenate(X,[H],T),
   ins(...). 
问题是它从后面在给定索引中插入元素
X
(我甚至知道问题在哪里->长度([T3],p),这显然是列表从后面开始的长度,而不是从开头开始的长度)。我试着记住当“截断元素的数量”=
P
时,我截断并插入了多少元素,但我不能在Prolog中真正写出这一点。有什么想法吗

% ins(Val,List,Pos,Res)

ins(Val,[H|List],Pos,[H|Res]):- Pos > 1, !, 
                                Pos1 is Pos - 1, ins(Val,List,Pos1,Res). 
ins(Val, List, 1, [Val|List]).

如果Pos=0或Pos>length(List)+1,则谓词将失败。让我们在这里说明您想要什么。例如,您可以说:“我想在
位置-1
元素之后拆分我的输入
列表
,以便在那里插入一个新元素”

append/3
直接交易(顺便说一句,DCG会更好):

或者你可以说:“我想在不碰任何东西的情况下浏览
列表中的元素
位置-1
次,然后插入
元素
,然后再也不碰任何东西。”

这一次的直接交易是:

ins2(Element, List, 1, [Element|List]).
ins2(Element, [Head|Tail], Position, [Head|Result]) :-
    Position > 1,
    NewPosition is Position - 1,
    ins2(Element, Tail, NewPosition, Result).
您也可以这样说:“我的输入
列表
是一个列表,它等于我的
结果
一,除了它没有我的
元素
作为
位置
第四个元素。”并且要意识到,如果使用swi prolog,谓词会立即解决这个问题:

ins3(Element, List, Position, Result) :-
    nth1(Position, Result, Element, List).

底线是:清楚地说明问题所在,解决方案应该简单明了。

TL;DR:要将项目
E
插入列表
Es0
中的位置
I1
,我们不需要编写递归代码

ins(Element,List,Nth,Result) :-
    length([_|L0],Nth),
    append(L0,[_|R],List),
    append(L0,[Element|R],Result).
相反,我们可以将这项工作(以及对如何正确完成这项工作的担忧)委托给多功能辅助谓词,所有这些都是任务的一部分。要定义
ins\u4
,我们写:

ins_(E, Es0, I1, Es) :- maplist(any_thing, Es, [_|Es0]), append(Prefix, Suffix, Es0), length([_|Prefix], I1), append(Prefix, [E|Suffix], Es). any_thing(_, _). % auxiliary predicate (used above) 让我们不要忘记最一般的查询

?- ins(X, Es0, I1, Es). Es0 = [], I1 = 1, Es = [X] ; Es0 = [A], I1 = 1, Es = [X,A] ; Es0 = [A], I1 = 2, Es = [A,X] ; Es0 = [A,B], I1 = 1, Es = [X,A,B] ; Es0 = [A,B], I1 = 2, Es = [A,X,B] ; Es0 = [A,B], I1 = 3, Es = [A,B,X] ; Es0 = [A,B,C], I1 = 1, Es = [X,A,B,C] ; Es0 = [A,B,C], I1 = 2, Es = [A,X,B,C] ; Es0 = [A,B,C], I1 = 3, Es = [A,B,X,C] ; Es0 = [A,B,C], I1 = 4, Es = [A,B,C,X] ; Es0 = [A,B,C,D], I1 = 1, Es = [X,A,B,C,D] ; ...
脚注1:上面显示的所有示例查询均以通用方式终止。
注2:GNU Prolog toplevel给出的答案已经打印了一点。

脚注3:上面给出的代码按原样使用,不需要额外的库谓词。

pos>1,newPos是p-1,wuaa这就是我要找的:)thx a lot虽然这段代码可以回答这个问题,但最好解释一下它是如何解决问题的以及为什么要使用它。从长远来看,只使用代码的答案是没有用的。查询?-ins_1;(a[1,2,3,4,5],3[1,2,a,3,4,5])。失败,应该会成功。如果查询
?-ins_(a[1,2,3,4,5],3[1,2,a,4,5])。
成功,则应失败。要修复此错误,您需要删除4个字符:) ?- ins_(X, [a,b,c,d,e], N1, Xs). N1 = 1, Xs = [X,a,b,c,d,e] ; N1 = 2, Xs = [a,X,b,c,d,e] ; N1 = 3, Xs = [a,b,X,c,d,e] ; N1 = 4, Xs = [a,b,c,X,d,e] ; N1 = 5, Xs = [a,b,c,d,X,e] ; N1 = 6, Xs = [a,b,c,d,e,X] ; false. ?- ins_(X, [a,b,c,d,e], 3, Xs). Xs = [a,b,X,c,d,e] ; false. ?- ins_(X, Xs0, 3, [a,b,c,d,e]). X = c, Xs0 = [a,b,d,e] ; false. ?- ins(X, Es0, I1, Es). Es0 = [], I1 = 1, Es = [X] ; Es0 = [A], I1 = 1, Es = [X,A] ; Es0 = [A], I1 = 2, Es = [A,X] ; Es0 = [A,B], I1 = 1, Es = [X,A,B] ; Es0 = [A,B], I1 = 2, Es = [A,X,B] ; Es0 = [A,B], I1 = 3, Es = [A,B,X] ; Es0 = [A,B,C], I1 = 1, Es = [X,A,B,C] ; Es0 = [A,B,C], I1 = 2, Es = [A,X,B,C] ; Es0 = [A,B,C], I1 = 3, Es = [A,B,X,C] ; Es0 = [A,B,C], I1 = 4, Es = [A,B,C,X] ; Es0 = [A,B,C,D], I1 = 1, Es = [X,A,B,C,D] ; ... % SICStus Prolog 4.3.2 % SWI Prolog 7.3.11 % % ?- ins3(X, Es0, I1, Es). % ?- ins3(X, Es0, I1, Es). I1 = 1, Es0 = [], Es = [X] % I1 = 1, Es = [X|Es0] ; % ; I1 = 2, Es0 = [_A|_Z], I1 = 1, Es0 = [_A], Es = [X,_A] % Es = [_A,X|_Z] ; I1 = 2, Es0 = [_A], Es = [_A,X] % ; I1 = 3, Es0 = [_A,_B|_Z], ; % Es = [_A,_B,X|_Z] I1 = 1, Es0 = [_A,_B], Es = [X,_A,_B] % ; I1 = 4, Es0 = [_A,_B,_C|_Z], ; I1 = 2, Es0 = [_A,_B], Es = [_A,X,_B] % Es = [_A,_B,_C,X|_Z], ; I1 = 3, Es0 = [_A,_B], Es = [_A,_B,X] % ; I1 = 5, Es0 = [_A,_B,_C,_D|_Z], ; % Es = [_A,_B,_C,_D,X|_Z] ... % ...