List 添加到列表如果列表中还没有,则更改列表中的元素(PROLOG)

List 添加到列表如果列表中还没有,则更改列表中的元素(PROLOG),list,prolog,append,List,Prolog,Append,我不熟悉Prolog,我正在尝试编写一个函数,检查给定的键是否在列表中;如果是,它将增加列表中的值,否则将附加到列表的末尾。这是到目前为止我的代码 placeKey( Key, [] , List2 ) :- append(Key,[], List2). %base case: append to empty list placeKey( Key, [K|Rest] , List2 ) :- %If front entry isnt the one we want then co

我不熟悉Prolog,我正在尝试编写一个函数,检查给定的键是否在列表中;如果是,它将增加列表中的值,否则将附加到列表的末尾。这是到目前为止我的代码

placeKey( Key, []       , List2 ) :- append(Key,[], List2).  %base case: append to empty list
placeKey( Key, [K|Rest] , List2 ) :-  %If front entry isnt the one we want then continue on the rest
  Key \= K ,
  put( Key ,Rest,List2).
placeKey(Key,[Key|Rest], List2):- %how to update item value?

然而,当项目不在给定列表中时,这只返回一个列表,我甚至不知道如何处理实际更改列表中项目的问题。任何帮助都将不胜感激

我会使用模式匹配而不是“命令”来解决任务:

placeKey(Key, [], [Key]).
placeKey(Key, [K|Rest], [K|List2]) :- Key \= K, placeKey(Key, Rest, List2).
...

有几种方法可以包含“键值”。一种是将键值对与连字符函子一起使用。我将从Capelical对基本问题的出色回答中自由借用,并添加关键的列表逻辑:

% Key not present, then it goes in with count 1
place_key(Key, [], [Key-1]).

% Key is at the head, then it's included in the new list with incremented count
% and the rest of the list is unchanged
place_key(Key, [Key-V|Rest], [Key-V1|Rest]) :-
    V1 is V+1.

% Current head is not the key, so it's just copied over and the rest
% of the list is processed
place_key(Key, [K-V|Rest], [K-V|List2]) :-
    Key \= K,
    place_key(Key, Rest, List2).
例如:

| ?- place_key(x, [], L).

L = [x-1] ? ;

no
| ?- place_key(x, [x-2,y-3,z-1], L).

L = [x-3,y-3,z-1] ? ;

no
| ?- place_key(w,[x-2,y-3,z-1], L).

L = [x-2,y-3,z-1,w-1] ? ;

no
键值格式的一个很好的方面是,ISO Prolog定义了一个谓词,
keysort/2
,可以识别它

| ?- place_key(q,[x-2,y-3,z-1], L), keysort(L, LX).

L = [x-2,y-3,z-1,q-1]
LX = [q-1,x-2,y-3,z-1] ? ;  % List sorted by key

no
| ?-
您还可以使用两个元素的子列表(
[Key,Value]
)来实现这一点,这可能是您的初衷,尽管还不清楚。如果需要,上述逻辑很容易适应这种格式。(无论您在哪里使用
K-V
模式,请将其替换为
[K,V]
),如果您对此类列表进行列表排序,它仍将按键排序:

| ?- sort([[c,1],[x,4],[d,5],[a,6],[m,2]], L).

L = [[a,6],[c,1],[d,5],[m,2],[x,4]]

yes
| ?-
像这样的

这使用一个
Key/Count
格式的元组来表示每个列表项

add_or_increment( Dict , K , Updated ) :-     % to add or increment a tuple in a dictionary-like list
  nonvar(K) ,                                 % - the key must be bound.
  append( Prefix , [K/N|Suffix] , Dict ) ,    % - use the key to find the tuple in the list.
  ! ,                                         % - eliminate the choice point.
  M is N+1 ,                                  % - increment the count
  append( Prefix , [K/M|Suffix] , Updated )   % - construct the updated list
  .                                           % - Easy!
add_or_increment( Dict , K , [K/1|Dict] ) :-  % otherwise, just prepend the key to the source list to create the updated list
  nonvar(K)                                   % - assuming, of course, that the key is bound.
  .                                           % - Even easier!