プロローグ プログラムを作成する場合、明確で具体的な問題ステートメントを書き留めて、問題を分解すると役立つ場合があります。何かのようなもの:
数値は回文であり、整数である場合、符号を無視して反転したときにその桁が同じである場合です。
これにより、問題のステートメントをほぼ要約した次のインターフェイス述語にたどり着きます。
%---------------------
% the public interface
%---------------------
palindromic_number(X) :- % A number is palindromic if
integer(X) , % - it is an integer, and
X >= 0 , % - it is greater than or equal to zero, and
reverse_digits(X,0,X) % - its decimal value is the same if you reverse its decimal digits
. % ... OR ...
palindromic_number(X) :- % it is palindromic, if
integer(X) , % - it is an integer, and
X < 0 , % - it is less than zero, and
X1 is - X , % - its absolute value
palindromic_number(X) % - is palindromic
. % Easy!
あとは、数字の桁を逆にする方法を見つけるだけです。上記の符号の処理を省略したことを考えると、それは簡単です: 右端から数字を取り除き、それらを結果の左端に追加して、ゼロになるまで続けます。
プロローグの便利なイディオムは、問題を再帰的に処理するときに最終結果が構築されるアキュムレータを取ることが多いプライベート ワーカー述語の前にパブリック述語を配置することです。また、この場合 (および他の多くの場合) には、通常、一般的なケースと 1 つまたはいくつかの特殊なケースがあります。ここで、計算を終了する特殊なケースは、ソース値がゼロの場合です。
これは、「数字の桁を逆にする方法」のこの定義につながります。
% ---------------------
% The worker predicate
% ---------------------
reverse_digits(0,T,T). % once we hit zero, the accumulator has the reversed number. Unify the accumulator with the desired result.
reverse_digits(X,T,Y) :- % Otherwise...
X > 0 , % - if X > 0,
X1 is X / 10 , % - compute the next X
D is X mod 10 , % - compute the nexst digit
T1 is 10*T + D , % - scale the accumulator and add the digit
reverse_digits(X1,T1,Y) % - recurse down.
. % - easy!
もちろん、別のアプローチは、数値を文字列 (個々の文字のリスト) に変換し、組み込みのreverse/2
述語を使用してそのリストを逆にし、それを元の値と統合することです。しかし、それがあなたのインストラクターが探しているものだとは思えません。