我有点麻烦。我写了一个函数,它返回列表中元素的出现次数。这是代码:
occurencesHelp(X,[],N,N).
occurencesHelp(X,[X|T],N,Y) :-
N1 is N+1,
occurencesHelp(X,T,N1,Y).
occurencesHelp(X,[H|T],N,Y) :-
occurencesHelp(X,T,N,Y).
occurences(X,List,N) :-
occurencesHelp(X,List,0,N).
这很好用,我得到的第一个答案是:
N = 5 ?
但是有多个答案,例如:
N = 4 ? ;
N = 4 ? ;
N = 3 ? ;
N = 4 ? ;
N = 3 ? ;
等等。我已经尝试过追踪,看看我能否理解为什么会出现这种情况,但无法弄明白。我认为使用切割会对我有所帮助,但我们已经明确告知不要使用切割,所以这不是一个选择。任何帮助将不胜感激。
感谢。
答案 0 :(得分:1)
当我在SWI-Prolog中加载代码时,我收到以下警告:
Warning: /home/isabelle/occ.pl:1:
Singleton variables: [X]
Warning: /home/isabelle/occ.pl:7:
Singleton variables: [H]
这些警告重要。单例变量通常表示您发生了严重的逻辑错误。在您的情况下,让我们看一下第7行。本节中的内容:
occurencesHelp(X,[H|T],N,Y) :-
occurencesHelp(X,T,N,Y).
Prolog告诉我们H
是一个单例变量。这意味着它只在该子句中出现一次,这意味着我们忘记将H
置于与其他变量的关系中。
前一条款(程序性地)说:"如果列表的头部是X
,则递增计数器"。相反,该条款应该说:"如果列表的头部不 X
,则保持计数器不变"。但它没有说清单的头部:事实上,它并没有说出H
的任何内容(因此警告)。
所以你需要添加的是一个目标,表明X
和H
应该是不相等的。表达此问题的两种方法是X \= H
和dif(X, H)
。在您的情况下,选择取决于您在课程中学到的内容。
(在这种情况下,第1行的单例警告是良性的;您只需将X
替换为_X
即可告诉Prolog您明确要忽略该变量。)