Prologで述語論理の存在記号∃をどうやって表現するのか?
Prologは一階述語論理をベースに作られているから、論理学の色々な記号を表すのは得意だろう、それなら存在記号∃を表すことも出来るのではないだろうかと思いいろいろ調べていたのですが、文法にはそれっぽいのなく、う~んできないのかな…と悩んでいました。
存在記号というのは
「人間の中には血液型がA型の人間が存在する」
などを表す記号です。
もうひとつ「全称記号∀」というのがあるのですが、これは「すべての」を表す記号で、例えば
「すべての人間は、呼吸をする」
などを表す記号です。
これはPrologで表すのは簡単で、
breathe(A):-human(A). % Aが人間であれば呼吸をするという述語
で表すことが出来ます。
Aというのが自由変数になっていてどのような対象にもマッチングするので、「すべての」が表現できるのです。
このプログラムに、例えば
human(taro). % taroは人間であるという記述
と追記し、プロンプトで
breathe(A).
と入力すると
A = taro.
(呼吸するのはtaro)
という返答が返ってきます。
そして始めの疑問に戻りますが、
上記の存在記号∃バージョンは果たしてどのように記述するのか。
「人間の中には血液型がA型の人間が存在する」
はどうPrologで記述するのか。
yahooの知恵袋や外国のstackoverflowで英語で質問してみたのですが、回答が得られず、あきらめかけていたのですが、以下のページを見てやっとわかりました。
Convert first-order logic expressions to normal form
このページの
4. Somebody has a car.
が
person(sk10).
car(sk11).
has(sk10, sk11).
に変換されているのを見てやっと分かりました
「なんでもいいから、何か」を登録すれば良いのです
human(someone).
bloodtype_A(someone).
これでOKです。
someoneというのはいったい誰なのか、それは自分もわからない。
とにかくそれは人間です。
そして、bloodtype_A(_)を満たす人間someoneが、間違いなく存在する。
これで∃の条件は満たされます。
ここで引数に自由変数を使ってしまうと、上で述べた「すべての」になってしまうのでアウトです。
さらにいうと、色々な述語をつくるときに、この someone という同じアトムを使いまわすとおかしくなる
(someoneは血液型がAでしかもBでとかになる)
ので、someoneの後ろに添え字を追加し、述語ごとにユニークにする必要があるでしょう。
気付けば単純なことなんだけど、なかなか思い至らなかった。
someoneはシンボルですから、aでもbでも良いはずで、
human(a).
bloodtype_A(a).
これで、「人間の中には血液型がA型の人間が存在する」
ということになるのですか?
>尾崎隆大さん
返信遅れ申し訳ありません。このブログに投稿されるほとんどのコメントがスパムのため普通のコメントが埋もれがちでチェックが遅れておりました。
はい、aでもbでもよくて、
human(a).
bloodtype_A(a).
で「人間の中には血液型がA型の人間が存在する」が表現できているということで良いです。
ただブログで記載しているとおり、ここで使ったaはもう他の論理式では使ってはいけないというところがポイントです。
このようなユニークなアトムを、例えばSWIで表現するとしたら、確かコールする度重複しないアトムを生成してくれる述語があったと思うので、これを使用すると実現可能だと思います(述語名失念しました)
上記のtermが、
human(john).
bloodtype_A(john).
でもやはり「人間の中には血液型がA型の人間が存在する」が表現できていますが、johnが実在の人間なので、johnについての別の事実を言及する場合はjohnを別の論理式に使っても良いです。
私の記事よりも紹介している以下のページのほうが参考になると思います。Prologの文を一階述語の論理式に変換するプログラムが載っています。
6.3 Convert first-order logic expressions to normal form
上記のページで表現しているいろんな論理式は(このままの形ではないですが)論理学の本(一階述語論理の説明があるもの)で目にするのでそういう本も合わせて参考にされると良いと思います。