学习prolog,一些列表功能

时间:2013-11-25 14:49:18

标签: prolog

我正在处理一项处理prolog中列表的任务。基本的想法是,给定一个列表,prolog应该能够确定一个值是否重复,重复一次,或只重复两次,等等。我认为最简单的解决方案是计算值发生的次数然后使用该计数来确定重复的次数。

list_count([],X,0).
list_count([X|T],X,Y) :- list_count(T,X,Z), Y is 1 + Z.
list_count([X1|T],X,Z) :- X1 \= X, list_count(T,X,Z).

repeated_in(+E,+List) :- list_count(List,E,Num), Num >= 2.

无论我做什么,虽然我的第一个谓词总是失败。帮助

2 个答案:

答案 0 :(得分:3)

list_count / 3确实有效。我认为唯一的问题是前缀'+'的使用不当:试试

% repeated_in(+E,+List)
repeated_in(E,List):- list_count(List,E,Num), Num >= 2.

注意:前缀参数用于文档目的,作为关于模式用法的回顾

答案 1 :(得分:2)

这是一个逻辑上纯粹的实现,基于 if_/3(=)/3 @false。

atLeastOnceMember_of(E,[X|Xs]) :-
   if_(E = X, true, atLeastOnceMember_of(E,Xs)).

atLeastTwiceMember_of(E,[X|Xs]) :-
   if_(E = X, atLeastOnceMember_of(E,Xs), atLeastTwiceMember_of(E,Xs)).

首先,让我们看一下您在问题中建议的查询:

?- atLeastTwiceMember_of(a,[a,b,a,b,a,c]).
true.                                       % succeeds deterministically
?- atLeastTwiceMember_of(b,[a,b,a,b,a,c]).
true.                                       % succeeds deterministically
?- atLeastTwiceMember_of(c,[a,b,a,b,a,c]).
false.
?- atLeastTwiceMember_of(x,[a,b,a,b,a,c]).
false.

代码单调,因此我们也可以获得逻辑上合理的答案以获得更多一般用途!

?- atLeastTwiceMember_of(X,[a,b,a,b,a,c]).
X = a ;
X = b ;
false.

最后,让我们考虑上述查询的泛化

?- atLeastTwiceMember_of(X,[A,B,C,D,E,F]).
X = A, A = B                                         ;
X = A, A = C, dif(C,B)                               ;
X = A, A = D, dif(D,C), dif(D,B)                     ;
X = A, A = E, dif(E,D), dif(E,C), dif(E,B)           ;
X = A, A = F, dif(F,E), dif(F,D), dif(F,C), dif(F,B) ;
X = B, B = C, dif(C,A)                               ;
X = B, B = D, dif(D,C), dif(D,A)                     ;
X = B, B = E, dif(E,D), dif(E,C), dif(E,A)           ;
X = B, B = F, dif(F,E), dif(F,D), dif(F,C), dif(F,A) ;
X = C, C = D, dif(D,B), dif(D,A)                     ;
X = C, C = E, dif(E,D), dif(E,B), dif(E,A)           ;
X = C, C = F, dif(F,E), dif(F,D), dif(F,B), dif(F,A) ;
X = D, D = E, dif(E,C), dif(E,B), dif(E,A)           ; 
X = D, D = F, dif(F,E), dif(F,C), dif(F,B), dif(F,A) ;
X = E, E = F, dif(F,D), dif(F,C), dif(F,B), dif(F,A) ;
false.