我正在尝试查看列表并计算给定单词出现的次数.到目前为止我有这个:
count_repetitions([_], [], 0).
count_repetitions([Word], [Word|Tail], Count):-
count_repetitions([Word], Tail, X),
Count is X + 1.
count_repetitions([Word], [Z|Tail], Count):-
Word \= Z,
count_repetitions([Word], Tail, Count).
Run Code Online (Sandbox Code Playgroud)
所以查询?- count_repetitions([yes],[yes,and,yes,and,no], X).会给出X = 2.
这似乎有效.现在我需要编写一个谓词,在表单中输出一个包含搜索词及其出现次数的列表X = [(yes - 2)].我完全陷入困境,有什么建议吗?
这个答案显示了一种逻辑上纯粹的方式.以下是基于clpfd.
:- use_module(library(clpfd)).
Run Code Online (Sandbox Code Playgroud)
:- meta_predicate tcount(2,?,?).
tcount(P_2,Xs,N) :-
N #>= 0,
list_pred_tcount_(Xs,P_2,0,N).
:- meta_predicate list_pred_tcount_(?,2,?,?).
list_pred_tcount_([] , _ ,N ,N).
list_pred_tcount_([X|Xs],P_2,N0,N) :-
if_(call(P_2,X), (N1 is N0+1, N1 #=< N), N1 = N0),
list_pred_tcount_(Xs,P_2,N1,N).
Run Code Online (Sandbox Code Playgroud)
现在让我们tcount/3结合使用(=)/3:
?- tcount(=(yes),[yes,and,yes,and,no],Count).
Count = 2.
Run Code Online (Sandbox Code Playgroud)
与此问题的所有其他答案所呈现的代码不同,此答案中提供的代码是单调的,即使在使用非基础术语时仍保持逻辑上的声音:
?- tcount(=(yes),[A,B,C,D],2).
A=yes , B=yes , dif(C,yes), dif(D,yes)
; A=yes , dif(B,yes), C=yes , dif(D,yes)
; A=yes , dif(B,yes), dif(C,yes), D=yes
; dif(A,yes), B=yes , C=yes , dif(D,yes)
; dif(A,yes), B=yes , dif(C,yes), D=yes
; dif(A,yes), dif(B,yes), C=yes , D=yes
; false.
Run Code Online (Sandbox Code Playgroud)
让我们尝试一些更普遍的东西:
?- tcount(=(yes),[A,B,C,D],Count).
A=yes , B=yes , C=yes , D=yes , Count = 4
; A=yes , B=yes , C=yes , dif(D,yes), Count = 3
; A=yes , B=yes , dif(C,yes), D=yes , Count = 3
; A=yes , B=yes , dif(C,yes), dif(D,yes), Count = 2
; A=yes , dif(B,yes), C=yes , D=yes , Count = 3
; A=yes , dif(B,yes), C=yes , dif(D,yes), Count = 2
; A=yes , dif(B,yes), dif(C,yes), D=yes , Count = 2
; A=yes , dif(B,yes), dif(C,yes), dif(D,yes), Count = 1
; dif(A,yes), B=yes , C=yes , D=yes , Count = 3
; dif(A,yes), B=yes , C=yes , dif(D,yes), Count = 2
; dif(A,yes), B=yes , dif(C,yes), D=yes , Count = 2
; dif(A,yes), B=yes , dif(C,yes), dif(D,yes), Count = 1
; dif(A,yes), dif(B,yes), C=yes , D=yes , Count = 2
; dif(A,yes), dif(B,yes), C=yes , dif(D,yes), Count = 1
; dif(A,yes), dif(B,yes), dif(C,yes), D=yes , Count = 1
; dif(A,yes), dif(B,yes), dif(C,yes), dif(D,yes), Count = 0.
Run Code Online (Sandbox Code Playgroud)
以下角落案例怎么样?
?- tcount(_,_,-1).
false.
Run Code Online (Sandbox Code Playgroud)
如何利用tcount/3替代品length/2?
?- N in 1..3, length(Xs,N). N = 1, Xs = [_A] ; N = 2, Xs = [_A,_B] ; N = 3, Xs = [_A,_B,_C] ... % does not terminate ?- use_module(library(lambda)). true. ?- N in 1..3, tcount(\_^ =(true),Xs,N). N = 1, Xs = [_A] ; N = 2, Xs = [_A,_B] ; N = 3, Xs = [_A,_B,_C] ; false. % terminates universally