在Prolog中: 我有以下函数来计算列表中某个元素的出现次数:
%count(L:list,E:int,N:int) (i,i,o)
count([],_,0).
count([H|T],E,C):-H == E,count(T,E,C1),C is C1+1.
count([_|T],E,C):-count(T,E,C).
我测试了它,效果很好。但问题来了,我还有另一项功能,必须检查是否" 1"在列表中发生的次数少于2次。
check(L):-count(L,1,C),C<2.
每当我尝试检查列表[1,1,1,1]
时,我得到的结果是&#34; true&#34;,这是错误的,我不明白为什么。我试图做一些改变,但功能刚刚起作用。
答案 0 :(得分:3)
改善您的测试习惯!
在测试Prolog代码时,不要仅查看某些查询的第一个答案并得出结论&#34; 它的工作原理&#34;。
非决定论 是Prolog的核心。
通常情况下,某些代码出现以便第一眼就能正常工作(查看第一个答案时),但在回溯时会出现问题(主要是错误答案和/或非终止)。
回到原来的问题...如果您想/需要保留logical-purity,请考虑使用以下代码@Ruben presented in his answer的最小变体:
count([],_,0). count([E|T],E,C) :- count(T,E,C1), C is C1+1. count([H|T],E,C) :- dif(H,E), count(T,E,C).
dif/2
以逻辑声音方式表达句法术语不等式。有关它的信息,请查看prolog-dif!
答案 1 :(得分:1)
这是因为count([1,1,1,1],1,1)
也是如此!在您的上一个count
中,当H等于E时,它也可以匹配。为了说明这一点,请使用;
使prolog查找count([1,1,1,1],1,R)
的更多答案。你会看到会发生什么。
count([],_,0).
count([E|T],E,C):-
count(T,E,C1),
C is C1+1.
count([H|T],E,C):-
H \= E,
count(T,E,C).
check(L) :-
count(L,1,C),
C < 2.
?- check([1,1,1,1,1]).
false
?- check([1]).
true
答案 2 :(得分:0)
第二和第三个子句头匹配相同的序列。作为最小的修正,我会提交测试
count([],_,0).
count([H|T],E,C):-H == E,!,count(T,E,C1),C is C1+1.
count([_|T],E,C):-count(T,E,C).