Prolog 序言:匹配一个或多个匿名变量

Prolog 序言:匹配一个或多个匿名变量,prolog,prolog-anonymous-variable,Prolog,Prolog Anonymous Variable,[[ux,[ux],[ux]将匹配类似于[d,[X,a],s]的列表。有没有办法将它与存在一个或多个匿名变量的任何模式相匹配?即[X,a],s]和[d,a],[p,z],[X,b]]会匹配吗 我正试图编写一个程序来计算列表中的元素,即[a,a,a,b,a,b]=>[a,4],[b,2]],但我被卡住了: listcount(L, N) :- listcountA(LS, [], N). listcountA([X|Tail], [? [X, B], ?], N) :- B is B+1, li

[[ux,[ux],[ux]将匹配类似于[d,[X,a],s]的列表。有没有办法将它与存在一个或多个匿名变量的任何模式相匹配?即[X,a],s]和[d,a],[p,z],[X,b]]会匹配吗

我正试图编写一个程序来计算列表中的元素,即[a,a,a,b,a,b]=>[a,4],[b,2]],但我被卡住了:

listcount(L, N) :-  listcountA(LS, [], N).
listcountA([X|Tail], [? [X, B], ?], N) :- B is B+1, listcountA(Tail, [? [X,B] ?], N).
listcountA([X|Tail], AL, N) :- listcountA(Tail, [[X,0]|AL], N).

谢谢。

[[ux,[uu],[uu]将只匹配具有3个元素的列表,第一个和第三个元素可以是原子或列表,第二个元素必须是长度为2的列表,但我希望您知道这一点。它不会匹配到2个元素列表,最好使用从头到尾的递归来查找元素并将其插入到结果列表中。 这是一个谓词草图,如果复制粘贴,我打赌它不会起作用;)


一个变量匹配一个术语,anonimus变量也不例外。列表只是头和尾之间的二进制关系的语法糖。因此,变量可以匹配列表、头部或尾部,但不能匹配未指定的序列

我希望一些注释可以帮助您:

listcount(L,N):-listcountA(LS,[],N)

在Prolog中,谓词由名称num.of.arguments标识,即所谓的functorarity。因此,通常带有附加参数的“服务”谓词保持相同的名称

listcountA([X | Tail],[X,B],?],N):-B是B+1,listcountA(Tail,[?[X,B]?],N)

B是B+1将永远不会成功,您必须使用新变量。而且,没有办法在列表中使用“通配符”进行匹配,就像您所做的那样。而是编写一个谓词来查找和更新计数器

最后一点注意:通常元素的使用二元关系表示,方便地使用一些(任意)运算符。例如,最常用的是破折号

所以我会写

listcount(L, Counters) :-
    listcount(L, [], Counters).

listcount([X | Tail], Counted, Counters) :-
    update(X, Counted, Updated),
    !, listcount(Tail, Updated, Counters).
listcount([], Counters, Counters).

update(X, [X - C | R], [X - S | R]) :-
    S is C + 1.
update(X, [H | T], [H | R]) :-
    update(X, T, R).
update(X, [], [X - 1]).  % X just inserted
update/3可以使用一些库谓词“在递归中移动”来简化。例如,使用select/3:

listcount([X | Tail], Counted, Counters) :-
    ( select(X - C, Counted, Without)
    ->  S is C + 1
    ;   S = 1, Without = Counted
    ),
    listcount(Tail, [X - S | Without], Counters).
listcount([], Counters, Counters).

我将在这篇文章的序言中说,如果你喜欢这个答案,请考虑给予@ CHAC的正确答案,因为这个答案是基于他们的。

以下是一个版本,它还使用累加器并处理输入列表中的变量,为您提供了直接要求的输出术语结构:

listcount(L, C) :-
    listcount(L, [], C).
listcount([], PL, PL).
listcount([X|Xs], Acc, L) :-
    select([X0,C], Acc, RAcc), 
    X == X0, !,
    NewC is C + 1,
    listcount(Xs, [[X0, NewC]|RAcc], L).
listcount([X|Xs], Acc, L) :-
    listcount(Xs, [[X, 1]|Acc], L).

请注意,
listcount/2
遵从基于累加器的版本,
listcount/3
,它维护累加器中的计数,并且不假设输入顺序或地面输入列表(命名/标记的变量可以正常工作)。

+1:这基本上就是我使用累加器来解决这个问题的方法。
listcount(L, C) :-
    listcount(L, [], C).
listcount([], PL, PL).
listcount([X|Xs], Acc, L) :-
    select([X0,C], Acc, RAcc), 
    X == X0, !,
    NewC is C + 1,
    listcount(Xs, [[X0, NewC]|RAcc], L).
listcount([X|Xs], Acc, L) :-
    listcount(Xs, [[X, 1]|Acc], L).