4

在 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]时,我得到的结果都是“真”,这是错误的,我不知道为什么。我试图进行一些更改,但该功能不起作用。

4

3 回答 3

3

改善你的测试习惯!

在测试 Prolog 代码时,不要只看某个查询的第一个答案并得出“它有效”的结论。

非确定性Prolog 的核心。

很多时候,一些代码乍一看似乎可以正常工作(在查看第一个答案时),但在回溯时会出现问题(主要是错误的答案和/或未终止)。


回到你原来的问题......如果你想/需要保留他的答案中提供的代码@Ruben的以下最小变体:

计数([],_,0)。
计数([E|T],E,C):-
   计数(T,E,C1),
   C是C1+1。
计数([H|T],E,C):-
   差异(H,E),
   计数(T,E,C)。

dif/2以合理的逻辑方式表达句法术语的不等式。有关它的信息,请查看

于 2015-11-20T16:25:11.820 回答
1

它发生是因为count([1,1,1,1],1,1)也是真的!在你的最后count,当 H 等于 E 时,它也可以匹配。为了说明这一点,使用;to make 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
于 2015-11-19T13:15:32.710 回答
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).
于 2015-11-19T13:19:32.370 回答