Prolog - 检查发生的次数是否按预期工作

时间:2015-11-19 12:49:04

标签: list prolog prolog-dif

在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;,这是错误的,我不明白为什么。我试图做一些改变,但功能刚刚起作用。

3 个答案:

答案 0 :(得分:3)

改善您的测试习惯!

在测试Prolog代码时,不要仅查看某些查询的第一个答案并得出结论&#34; 它的工作原理&#34;。

非决定论 是Prolog的核心。

通常情况下,某些代码出现以便第一眼就能正常工作(查看第一个答案时),但在回溯时会出现问题(主要是错误答案和/或非终止)。

回到原来的问题...如果您想/需要保留,请考虑使用以下代码@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以逻辑声音方式表达句法术语不等式。有关它的信息,请查看

答案 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).