Prolog 写経記 その 48 age/3

(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.

Prologユーティリティライブラリ

Prologユーティリティライブラリ

今日は age/2 を写経します.

解説

age(X, Y) はアトム X とアトム Y とがアルファベット文字列として等しいか,アルファベット順にみて XY より後ろにあるときに成功する.

age って age/sage の age じゃなくて,ASCII の greater equal っすか.
Java でいうと... String#compareTo(String) で結果が 0 以上 (≧)みたいな.

モード

age(+, +).

ふーん.またしても + 二つですか.

定義

では,こいつの定義を写経しませう.

age(X, Y) :-
	name(X, L),
	name(Y, M),
	age_ASCII(L, M).

age_ASCII([], []).
age_ASCII([_ | _], []).
age_ASCII([H | Q], [H | S]) :-
	!,
	age_ASCII(Q, S).
age_ASCII([X | _], [Y | _]) :-
	X > Y.

うぎゃ,昨日のと違ってずいぶんと複雑な感じ.
age/2 本体は特に何もやっていないに近いですね.アトムを文字コードのリストにしているだけ.今回は XY を異なった変数に具体化しているので,XY とも具体化されていないとダメですね.たしかに age(+, +) になってます.


んで,次の age_ASCII/2 が事実上の本体.
最初の節は終了条件かなぁ.greater equal なので両方空リストつまり等しければ成功.
次の節は,第 1 引数が空でなくて第 2 引数が空リスト.つまり第 1 引数の方が長かった場合なので成功.
3 番目の節は二つのリストの最初の文字が等しかった場合.その場合は再帰します.
最後の節は二つのリストの最初の文字が異なる場合.第 1 引数の最初の文字 X (の ASCII コード) が第 2 引数の最初の文字 Y (の ASCII コード)よりも大きければ成功.
うむ.

注記

age は比較対象がアトムでないときは失敗する.

らじゃあ.
っていうか,昨日はうまくいかなかったわけですが.

では使用例を写経しませう.

2 ?- age('Word', 'Word').

Yes
3 ?- age(predicate, pred).

Yes
4 ?- age('Jane', 'John').

No
5 ?- age(-13.7, -13.7).

Yes

最後の例,写経本では冷たく No と言われてお終いなんですが,昨日の例と同様,成功しちゃいます...
name/2 に数値を渡した場合の振る舞いについてはいずれ調査するということで.