List Prolog-检查发生次数不';I don’我没有按预期工作

List Prolog-检查发生次数不';I don’我没有按预期工作,list,prolog,prolog-dif,logical-purity,List,Prolog,Prolog Dif,Logical Purity,在序言中: 我有以下函数,用于统计列表中某个元素的出现次数: %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. c

在序言中: 我有以下函数,用于统计列表中某个元素的出现次数:

%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.

check(L):-count(L,1,C),C之所以发生这种情况,是因为
count([1,1,1,1],1,1)
也是真的!在上一次的
计数中
也可以在H等于E时进行匹配。要说明这一点,请使用
使prolog查找更多关于
计数([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.

第二和第三个从句的开头匹配相同的顺序。作为最低限度的更正,我将进行测试

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

改进您的测试习惯

在测试Prolog代码时,不要只看某个查询的第一个答案,就得出“它可以工作”的结论

非决定论是序言的核心

通常,一些代码乍一看似乎工作正常(当看到第一个答案时),但回溯时会出现问题(主要是错误答案和/或不终止)


回到你最初的问题。。。如果您需要/需要保存,请考虑使用以下代码的最小变化:

计数([],\u0)。 计数([E | T],E,C):- 计数(T,E,C1), C是C1+1。 计数([H | T],E,C):- dif(H,E), 计数(T,E,C)。
dif/2
以合乎逻辑的方式表达语法术语不等式。有关它的信息,请查看

注意语义是不同的,可能是无意的,OP的原始测试不能被统一所取代。非常感谢,我刚刚发现我忘了在第二个子句中插入“切口”,但由于你的回答,我看到了哪里出了问题,两个版本都可以工作。请看下面关于非常相关的问题的答案!
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).
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).