此答案显示逻辑纯的方式来做到这一点。以下是根据clpfd。
:- use_module(library(clpfd)).
我们定义meta-predicatetcount/3
类似tfilter/3
!
:- 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).
现在让我们使用tcount/3
结合(=)/3
:
?- tcount(=(yes),[yes,and,yes,and,no],Count).
Count = 2.
与通过所有其他答案提出这个问题的代码,在这个答案的代码都是单调和逻辑上仍然即使在非地面条件下使用时也会发出声音:
?- 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.
让我们尝试一些更普遍:
?- 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.
什么下面的角落呢?
?- tcount(_,_,-1).
false.
又有怎样利用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
感谢您的解决方案鲍里斯。有X = [是 - 2]是我的一个错字,它不需要在括号中。再次感谢! – dlmb