Prolog 写経記 その 85 not/1

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

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

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

今日は not/1 を写経します.

解説

not(X) は否定を実行する.すなわち X が失敗すれば成功し,成功すれば失敗する.

モード

not(+)

ふむ.

定義

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

not2(X) :-
	call(X), !,
	fail.
not2(_).

not/1 は既に定義済みなので not2 にしました.


短い述語ですが,結構味わいがありますねぇ.
最初の節で call/1 により呼び出された述語 X が成功すると,その後の fail/1 によりこの節は失敗します.
そして fail/1 の前にカットが付いているため,バックトラックも行われず,述語全体が失敗に終わります.
一方,call/1 により呼び出された述語 X が失敗するとトラックバックにより 2 番目の節へ試されますが,2 番目の節は無条件に成功します.
そんなわけで (どんなわけで?),この述語は述語 X の結果と逆になるわけですね.

注意

not はゴールに適用されるメタ論理述語である.not をたとえば :-op(900, fy, not) のような演算子として定義すると,記述を簡潔にできる.これより not(number(X)) の代わりに not number(X) と書ける.
否定の使用には注意を要する.Prolog の否定は失敗による否定として知られている.この原理は存在するものすべてはプログラム中に含まれているかあるいは推論できるとする,閉世界仮説にもとづいている.あるものがプログラム中に見つけられず待たす異論もされない場合,それは真ではなくなり,それ故その否定が真となる.従ってゴールの否定が成功したということはそのゴールが失敗したか (2 番目の例参照),あるいはそのゴールを満たす情報が存在しなかったことを示している (3 番目の例参照.ただし weather(cloudy) がデータベース中にないと仮定している).

閉世界仮説... そんな難しい言葉知らないよ.(;_;)
でもまぁ,言ってることは分かる.
未定義も失敗と同じってことですよね.

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

2 ?- not2(number(1)).

No
3 ?- not2(number(one)).

Yes
4 ?- not2(weather(cloudy)).
ERROR: Undefined procedure: weather/1

ぐはぁっ,どういうことよっ!?
...
そうか,weather/1 自体が存在しないとこうなっちゃうわけですか.
つまり,

weather(rain).

とか登録しておかないといけないわけね.

6 ?- not2(weather(cloudy)).

Yes

そういうことか.
未定義といっても,述語が全く存在しないと話にならないよ,と.
らじゃあ.


ついでに

:-op(900, fy, not2).

も定義してみました.

7 ?- not2 number(1).

No
8 ?- not2 number(one).

Yes
9 ?- not2 weather(cloudy).

Yes

ふむ.いいっすね♪