如果我在Prolog的一个列表,如X = [1,2,3,4],如何元件5添加到列表的末尾有X = [1,2,3,4,5]?
该附加功能需要两个列表,即追加(A,B,C)来获得A和B级联到列表C.
我可以用临时列表为此Y = [1,2,3,4]和Z = [5],以然后执行追加(Y,Z,X),但我不喜欢的临时列表。
通常免责声明适用于这里 - 这不是做作业,我刚学的Prolog。
如果我在Prolog的一个列表,如X = [1,2,3,4],如何元件5添加到列表的末尾有X = [1,2,3,4,5]?
该附加功能需要两个列表,即追加(A,B,C)来获得A和B级联到列表C.
我可以用临时列表为此Y = [1,2,3,4]和Z = [5],以然后执行追加(Y,Z,X),但我不喜欢的临时列表。
通常免责声明适用于这里 - 这不是做作业,我刚学的Prolog。
在Prolog的变量只能被分配一次。 只要X值[1,2,3,4]它永远不能拥有另一个值。 一个临时变量和追加/ 3,如你所说,是要做到这一点。
说了这么多,你能做到这可能不推荐一招。 如果X = [1,2,3,4,Y]那么你可以做Y = 5和X现在有你想要的值。 我相信,这种技术被称为差异列表。
正如其他人所指出的那样,你要与性能问题被卡住。
但只是作为一个练习,我决定尝试创造一种可以一个元素添加到列表的最后一个谓语,而无需使用append
。
% add_tail(+List,+Element,-List)
% Add the given element to the end of the list, without using the "append" predicate.
add_tail([],X,[X]).
add_tail([H|T],X,[H|L]):-add_tail(T,X,L).
我会建议你会简单地使用append
功能,如内置的功能,有可能比任何手工制作的速度更快。
一个说明性解决方案是使用一个差异列表(丹尼尔在其答案的建议)。 和它的尾巴清单:一个差异列表被通常表示为两个表之间的差异而得名。 例如,一个空的列表可被表示为TT
。 列表1,2和3可被表示为元素[1,2,3| T]-T
[1,2,3| T]-T
(注意(-)/2
是标准内置缀运算符)。 这种表示的优点是,可以通过使用单个事实定义追加到恒定时间列表中的一个元件append/3
谓词:
append(L1-T1, T1-T2, L1-T2).
一个使用示例:
?- append([1,2,3,4| T1]-T1, [5| T2]-T2, Result).
T1 = [5|T2],
Result = [1, 2, 3, 4, 5|T2]-T2.
如果必要的话,不难一个“正常”的列表和差异列表之间的转换。 我将它作为一个练习给你。
你担心的问题错误的结束。 结构共享可以通过consing元素只发生到列表的开头。 这种方法有你想要的性能特性。 由于该方式定义列表,当你追加两个名单,整个名单第一次将被复制。 在这种情况下,将是整个列表。 由一个项目清单中产生的垃圾,显然会比要小得多。
如果你真的必须追加,考虑向后建筑列表,然后在年底,这是便宜得多,一旦逆转,或使用差异表,这使高效追加到最后。
您不能修改列表中的Prolog,但你可以创建一个未指定长度的列表:
main :-
A = [1,2,3,4|_].
然后,你可以插入使用元素nth0/3
在SWI-Prolog的:
:- initialization(main).
main :-
A = [1,2,3,4|_],
nth0(4,A,5),
writeln(A).
后这个元件被插入, A = [1,2,3,4,5|_]
您也可以定义附加到就地列表的最后一个项目的功能,然后用它是这样的:
:- initialization(main).
append_to_list(List,Item) :-
List = [Start|[To_add|Rest]],
nonvar(Start),
(var(To_add),To_add=Item;append_to_list([To_add|Rest],Item)).
main :-
A = [1,2,3|_],
append_to_list(A,4),
append_to_list(A,4),
writeln(A).
在这个例子中, A = [1,2,3,4,4|_]
之后这两个项目被附加。
由于Prolog有追加只接受列表,我们为什么不使用它来插入我们的元素在列表中的一个。 即
% E = element, L = list, R = result
% e.g. add_elem_in_list ([1,2,3,4], 5, R).
add_elem_in_list(L, E, R) :- append(L, [E], R).