些細な質問ですが、プログラムが特定の数値以下の数値のリストを返すようにしたいと考えています。たとえば、CountD(4,L)
. 与えるべき[4,3,2,1]
です。これは私がこれまでに持っているものです:
CountD(1,[]).
CountD(Num,List):- [Num|List], CountD(M,List), Num is M+1.
些細な質問ですが、プログラムが特定の数値以下の数値のリストを返すようにしたいと考えています。たとえば、CountD(4,L)
. 与えるべき[4,3,2,1]
です。これは私がこれまでに持っているものです:
CountD(1,[]).
CountD(Num,List):- [Num|List], CountD(M,List), Num is M+1.
@Borisの答えは完璧です。元のプログラムと別の回答のプログラムが終了しない理由を説明したいと思います。
一見すると、うまくいくように見えますが、結局のところ、答えが得られます。
?- countD(4,L).
L = [4, 3, 2, 1]
しかし、プロローグは最初の答えしか示していないことに注意してください.もっと待っています...
?- countD(4,L).
L = [4, 3, 2, 1] ;
**LOOPS**
Prolog での終了を理解する最善の方法は、プログラムの関連部分に集中することです。Prolog の優れた点は、実際の制御フローは非常に複雑ですが、多くの場合、プログラムの非常に小さな部分を調べて特定のプロパティを決定するだけで十分です。ですから、「一度にすべてを理解する」必要はありません。
すべてを見る代わりに、次の失敗スライスを取り上げます。
countD(0,[]) :- false. countD(数値、リスト) :- リスト = [Num|L], countD(M,L), false ,Num は M+1.
最初の行では、ファクトに挿入false
することにより、ファクトが効果的に削除されます。したがって、正確に何を記述しても、0
or1
はこの述語の終了に影響を与えません。一般に、障害スライスが終了しないということは、元のプログラムが終了しないことを意味します。
もちろん、適切なスライスを見つける必要があります。ちょっとした経験です。しかし、いったん見つかったら、その終端特性は簡単に確認できます。
この問題を解決するために、さらに句を追加しても終了は改善されないとすぐに言えます (プログラムが純粋で単調なものである場合)。目に見える部分で何かを変更する必要があります。Boris はNum
、実際の再帰の前にいくつかのチェックを追加することでこれを行いました。
countD(0,[]).
countD(Num,List) :- List = [Num|L], countD(M,L), Num is M+1.
更新しました:
コメントで @false と @boris が見つけた問題を修正します。
countD(Num,[Num|L]) :- Num > 0, M is Num-1, countD(M,L).
countD(0,[]).