ここには 2 つの主な問題が潜んでいます。
1- 適切な場所で統一と算術演算を取得するのに問題がある
2-入力を十分にチェックしていません
1- について の注意(is)/2
は、算術を実行するために使用されます。ここでは、たとえば、 を減算1
しLimit
ます。(is)/2
変数を既に評価された算術式に統一するために使用することはできますが、使用すべきではありません。(=)/2
優先する必要があります(統合)。
2 についての注意事項 - 演算子を正しく設定しても、プログラムはループします。それについては後で詳しく説明します。
オペレーターを自分で切り替えるだけではあまり得策がないため、正しい方法は次のとおりです。
numberList([], 0).
numberList([Limit|T], Limit) :-
NewLimit is Limit - 1,
numberList(T, NewLimit).
ここで、2 番目の節の先頭で暗黙的に統一を使用していることがわかります。別の言い方をすると、次のようになります。
numberList([], 0).
numberList([H|T], Limit) :-
H = Limit,
NewLimit is Limit - 1,
numberList(T, NewLimit).
しかし、このプログラムを試してみるとわかるように、正しい解を見つけますが、別の解を求めるとループします;
。
その理由は、初心者の目には見つけにくいかもしれません。Prolog が成功して解を返した場合、実行中に残された選択ポイントを探索することによってのみ、新しい解を見つけることができます。ここで、残された唯一の選択ポイントは が である場合Limit
です0
。したがって、その場合、最初の節ではなく 2 番目の節を試行し、到達するまでループしますNegativeInfinity
。悲しいことに、そこに着くまでの距離がかなり長いため、前にオーバーフローします。この問題の解決策は、2 番目の句にガードを追加して、Limit
それよりも大きい必要があることを指定する0
か、最初の句にカットを追加するか、さらに良い方法で両方を行うことです。自分でやるのが苦手な方はご相談ください!