1

これは私のコードです:

numeral(0).
numeral(succ(X)) :- numeral(X).

convertToD(A,0).  
convertToD(succ(S), Y) :- numeral(S), Y1 is Y-1, convertToD(S, Y1). 

なぜこれが私にそのような出力を与えるのですか?

convertTo(succ(succ(0)), N).
N = 0 ;
ERROR: convertTo/2: Arguments are not sufficiently instantiated
4

1 に答える 1

2

さて、あなたはこれのために複数の答えを得ています:

convertToD(A,0).

ここで意味するのは、 「convertToDは0の場合は0」を意味する場合、「convertToDはすべてと0convertToD(0, 0)間で真である」と言っているためです。これは、Prologがあなたが複数の結果を持っていると考える理由でもあります。

いくつか考えて、この質問が重複している質問に気づいたので、2番目の句で何を達成しようとしていたかわかります。あなたがやろうとしていることは、通常のPrologでそこからclpfdソリューションをエミュレートすることです。clpfdを使用する場合:

convertToD(succ(S), Y) :- numeral(S), Y0 #= Y-1, convertToD(S, Y0).

それをバニラPrologに直接コピーすると、ここにコードが表示されますが、clpfdがテーブルにもたらすすべての魔法は起こりません。clpfdがないと、インスタンス化の組み合わせに対して機能し、ループしない述語を作成することは非常に困難です。役立つことの1つは、算術演算を最後に移動することです。

convertToD(succ(S), Y) :- numeral(S), convertToD(S, Y1), succ(Y1, Y).

これにより、ここでループすることを除いて、すべての望ましいプロパティを持つ述語が得られます。

?- convertToD(X, 3).
X = s(s(s(0))) ;
^CAction (h for help) ? abort

私はこれをwhen/2and var/1/nonvar/1でいじりましたが、その小さな問題を解決することができませんでした。

于 2013-02-22T19:07:39.067 に答える