我有一个问题在序言列表添加元素。 我用这个规则:
add(X, L, [X|L]).
这条规则在列表的头部添加元素。 如果我将一些元素添加到同一列表我有这样的问题:
add(a, L, L1),
add(b, L1,L2),
add(c, L2,L3).
L3= [a,b,c]
有没有在列表中添加元素,而无需改变变量... L1,L2,L3的名称的方法,但增加他们到一个变量L?
我有一个问题在序言列表添加元素。 我用这个规则:
add(X, L, [X|L]).
这条规则在列表的头部添加元素。 如果我将一些元素添加到同一列表我有这样的问题:
add(a, L, L1),
add(b, L1,L2),
add(c, L2,L3).
L3= [a,b,c]
有没有在列表中添加元素,而无需改变变量... L1,L2,L3的名称的方法,但增加他们到一个变量L?
简短的答案是否定的:L将有机会代表不同的列表,这是错误的序言。
但是,你可以实现这样的事情:
add_list([], L, L).
add_list([H|T], L, L1) :- add(H, L2, L1), add_list(T, L, L2).
用法示例:
?- add_list([1,2,3],X,A).
A = [1, 2, 3|X].
?- add_list([1,2,3],X,A), writeln(A-X), add_list([4,5],Y,X).
[1,2,3|_G1188]-_G1188
X = [4, 5|Y],
A = [1, 2, 3, 4, 5|Y].
?- add_list([1,2,3],X,A), writeln(A-X), add_list([4,5],Y,X),Y=[].
[1,2,3|_G1224]-_G1224
X = [4, 5],
A = [1, 2, 3, 4, 5],
Y = [].
这是隐含DCG完成后,加入(隐藏),差分列表参数非终端。 但是,如果没有你的任务更加详细很难暗示任何合理的使用。
SWI-Prolog的实际上有一些严重的能力,通过非backtrackable数据结构,执行与“副作用”传播直通解决方案链的任务,但我不知道,如果是适当时候提示你这个功能...
编辑更新在故障驱动环的RBTree的示例:
:- use_module(library(rbtrees)).
:- use_module(library(nb_rbtrees)).
ordkey :- rb_empty(R),
forall(member(W, [ls,mkdir,cd,ftp]),
( atom_length(W, K),
( nb_rb_get_node(R, K, N)
-> nb_rb_node_value(N, Ws),
nb_rb_set_node_value(N, [W|Ws])
; nb_rb_insert(R, K, [W])
)
)), rb_visit(R, L), writeln(L).
yields
?- ordkey.
[2-[cd,ls],3-[ftp],5-[mkdir]]
简短的回答,如上所述,是NO。
较长的答案:不能项目添加到现有列表(不创建一个新的列表)。 你也可以增加一个变量就像你可能在其他语言:你只能创建一个新的变量,其值是1的Prolog的数据类型的增加都是不可变源变量。 Prolog的变量,一旦绑定到一个值, 不再是可变的 。 他们的结合是百废待兴的时候执行回溯完成作业。
虽然你不能只是添加到现有的列表,它对应于直接的问题被问,有某几类问题,可以使用谓词,其解决方案是单独要在列表收集物品来解决,你可以他们收集与ISO谓词findall
:
determin_item( ..., X ) :-
% Logic which determines X
% Could be complex with multiple Prolog statements and various conditionals
findall( X, determine_item(..., X), List ).
作为用于给定的情况下的简单的例子:
foo(1,a).
foo(1,b).
foo(1,c).
foo(2,e).
foo(3,f).
determine_item( X ) :-
foo(1, X). % Trivial example to determine X
findall( X, determine_item(X), List ).
这将产生:
List = [a,b,c].