count_element(Element, List, Result) :-
count_element(Element, List, 0, Result). % here I start the real rule with counter initialized to 0
count_element(Element, [], Counter, Counter). % if it arrives to the end of the list so there isn't any other element, Result is Counter.
count_element(Element, [Head | Rest], Counter, Result) :- % if Head is Element, Counter increments
Head =:= Element,
NewCounter is Counter+1.
count_element(Element, Rest, NewCounter, Result). % start recurively the function with the list without the head
count_element(Element, [Head | Rest], Counter, Result) :- % if head is not the element, simply start recursively maintaining the counter
Head = Element,
count_element(Element, Rest, Counter, Result).
我得到这个:
?- count_element(3,[1,2,3,3],R).
true ;
true ;
true ;
true ;
false.
但没有那个元素发生了多少次的结果。。。
其他有趣的结果:
?- count_element(3,[3],R).
true ;
true ;
false.
?- count_element(3,[1],R).
true ;
R = 0 ;
true ;
false.
?- count_element(3,[],R).
R = 0 ;
true ;
false.
您有很多单态。这是你在做什么的代码气味不太对。
此外,这将左侧和右侧作为算术表达式进行评估,并比较结果:
Head =:= Element
同时这测试左手侧是否能够与右手侧统一。
一个不是另一个的反面。
Prolog有多种口味的";"平等";。
你可能想要的是==/2
和==/2
,它们与等价项进行比较,但变量只等于它们自己。没有进行统一(例如,变量A
只等价于它自己,它与变量_
、B
或C
不等价,它与原子、项或数不等价(。
重写您的示例(使用稍短的变量名(,我们得到:
count_element( E, Ls, R ) :- count_element( E, Ls, 0, R ) .
count_element( _ , [] , C , C ) .
count_element( E , [H|T] , C , R ) :- H == E, C1 is C+1, count_element(E,T,C1,R) .
count_element( E , [H|T] , C , R ) :- H == E, count_element(E,T,C,R) .
我们可以通过引入切割(!/0
(来简化这一点,以消除H == E
处的选择点(这两个项目已经被发现是等价的,在回溯时不会神奇地变得不等价(。
这给了我们这个:
count_element( E, Ls, R ) :- count_element( E, Ls, 0, R ) .
count_element( _ , [] , C , C ) .
count_element( E , [H|T] , C , R ) :- H == E, !, C1 is C+1, count_element(E,T,C1,R) .
count_element( E , [H|T] , C , R ) :- count_element(E,T,C,R) .
或者,您可以使用软切割(Condition -> Then ; Else
(。这给了我们:
count_element( E, Ls, R ) :- count_element( E, Ls, 0, R ) .
count_element( _ , [] , C , C ) .
count_element( E , [H|T] , C , R ) :-
( H == E -> C1 is C+1, C1 = C ),
count_element(E,T,C1,R)
.