一个变量匹配一个term,anonimus 变量也不例外。列表只是头尾之间二元关系的语法糖。所以一个变量可以匹配列表、头部或尾部,但不能匹配未指定的序列。
我希望对您有所帮助的一些注意事项:
listcount(L, N) :- listcountA(LS, [], N)。
在 Prolog 中,谓词由 name和num.of.arguments 标识,即所谓的functor和arity。所以通常带有附加参数的“服务”谓词保持相同的名称。
listcountA([X|Tail], [? [X, B], ?], N) :- B 是 B+1, listcountA(Tail, [? [X,B] ?], N)。
B is 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).