2017-01-04 6 views
1

何か問題があります。私は、リスト内の要素の出現回数を返す関数を書いています。Prolog:複数の回答を返すリスト内の要素の出現をカウントする

N = 5 ? 

が、その後のような複数回答あります:これは正常に動作します

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 = 4 ? ; 
N = 4 ? ; 
N = 3 ? ; 
N = 4 ? ; 
N = 3 ? ; 

とは、ここでは、コードです。私はそれがなぜそうであるかを見ることができるかどうかを調べるためにトレースを試みましたが、それを理解することはできません。私はカットを使用すると私を助けると思うが、カットを使わないように特別に言われているので、これはオプションではない。どんな助けもありがとう。

ありがとうございました。

答えて

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がシングルトン変数であることを教えてくれる。これは、この節で1回だけ発生することを意味します。つまり、は、他の変数との関係でHを入れることを忘れていました。

前の節には、(手続き的に)「リストの先頭がXの場合は、カウンタを増分する」と記載されています。逆に、この句は、「リストの先頭がではない場合、Xではないので、カウンタを変更しないでください。しかし、それはリストの頭について言わない:実際には、Hについての何も言わない(したがって警告)。

だから、あなたが追加する必要があるのは、XHが等しくなければならないという事実を表す目標です。これを表現する2つの方法は、X \= Hdif(X, H)です。あなたの場合、その選択はあなたのコースで既に学んだことによって決まります。

(1行目のシングルトンの警告は、この場合には良性であり、あなたはちょうどあなたが明示的にその変数を無視することをプロローグに伝えるために_XXを置き換えることができます)

+0

は、Xを追加し、返信いただき、誠にありがとうございます\ = Hは本当に問題を解決します。明確にするために、なぜこれを明示的に指定する必要があるのですか?私が理解しているところでは、X = Hならカウンタをインクリメントする節を使い、X \ = Hならばそれをそのまま維持する節に行くでしょう。カウンターをX = Hで変更しないでおく句のインスタンスがあるのはなぜですか?これが些細なことであれば、ちょうど私の頭を包み込むようにしようとすると謝罪します。ありがとう。 – Faz

+0

@Fazあなたの2番目のケースが明示的に 'X \ = H'を強制しない場合、' X = H 'のケースは両方のケースにマッチします。覚えておいてください:Prologはあなたのルールに合致するすべての可能な解決策を探します。 – lurker

関連する問題