私は SWI Prolog を使用して大学の試験のために Prolog を勉強していますが、次の問題の 2 つの異なるソリューションの違いについて疑問があります。
Xはアトム、L はリスト、 NumXは X が L に現れる回数です。
これが最初の解決策です:
count0(_,[],0).
count0(A, [A|Tail], N) :-
count0(A,Tail,N1), % L'elemento cercato appare N1 volte nella sottolista
N is N1+1. % N vale N1+1
count0(A, [B|Tail], N) :-
A\=B, % A è diverso da B
count0(A,Tail,N). % N è il numero di occorrenze di A nella sottolista
これが 2 番目の解決策です。
count1(_,[],0).
count1(A, [A|Tail], N) :- !,
count1(A, Tail, N1),
N is N1+1.
count1(A, [_|Tail], N) :- count1(A, Tail, N).
私の問題は、2 番目のバージョンで CUT が果たす役割を理解していないことです。
CUT は、CUT が配置されている特定のポイントでバックトラックを防止することを知っています。
プログラムの最初のバージョンは、A が 2 番目のルールで B と異なるかどうかをチェックします (これが必要ですか? 最初のルールが失敗した場合は、A がリストの HEAD と統合されないため、ヘッドのリストAの要素とは異なります)
2 番目のバージョンは、2 番目のルールでこのチェックを実行せず、最初のルールにカットを入れます...
それは、(2 番目のバージョンで) バックトラッキングを防止しないと、次のことが起こるという事実に依存する可能性があります。2番目のルールを使用することが起こります:
count1(A, [_|Tail], N) :- count1(A, Tail, N).
計算で別の分岐を取り、その分岐では N がありません N+1 ですか?