MkItYs

MkItYs > AI・交渉・物語の自動生成 > 

images

ChatGPT (GPT-3.5) にPrologで関係のルールを教えてみる:GPT-3.5, Prolog (SWI-Prolog)

images

- 2023.03.14

ChatGPT (GPT-3.5) に、Prologで関係のルールを教えてみましたーーうまくすれば、チャットのときのルールベースのメモリに使えるかもしれません。

関連


ChatGPT (GPT-4) にPrologで関係のルールを教えてみる:GPT-4, Prolog (SWI-Prolog)
大規模言語モデル/音声認識/音声合成/感情分析を使う:ChatGPT (gpt-3.5-turbo) , GPT-3 (text-davinci-003) , FlexGen, Azure Cognitive Services (Speech SDK)

結論


結論としてはーー会話のときのメモリに、Prologもそれなりに活用できそう、というところでしょうか:

ルールベースのメモリに使える(ときもある……すくなくとも自然言語で指示するよりは)
ルールは簡潔に・明瞭に書ける(ので、コストの削減にはなる)

概要


言語には言葉どうしのさまざまな関係があります。

たとえば「はるこのおかあさんはなつこ、なつこのおかあさんはあきこ」と言われたら、「はるこのおばあちゃんはあきこ」と返せますーー親子関係をあらわす言葉のルールがあるからですね(「おかあさんのおかあさんはおばあちゃん」)。

大規模言語モデルのChatGPT もそういったさまざまなルールを学習しているはずですが、どんなルールを知っているかは、試してみないと分かりません。

ここではChatGPT に、より明確に・簡潔に言葉のルールを教えて、ちゃんと覚えてくれるかどうかを確かめてみたいと思いますーーうまくすれば、チャットのときのルールベースのメモリに使えるかもしれないので。

いろいろな関係のルールを記述するのに有名な言語といえば、PrologですーーそしてChatGPT なら、Prologもそれなりに学習しているはずです。[※1]


※1
Prologのじっさいの動作を試すには、たとえば次のインタプリタがありますーーコンテナがあればすぐに使えます:
SWI-Prolog

前提


そもそもChatGPT は、Prologを知ってるんでしょうか? 代表的な式を与えてみましょう:

死ぬ(X):-ひと(X).
ひと(ソクラテス).
死ぬ(X).
このコードは、Prologと呼ばれるプログラミング言語で書かれたもののようです。

このコードの意味は、「Xが死ぬということは、Xは人間である」という規則を定義し、「ソクラテスは人間である」という事実を与えた上で、「ソクラテスは死ぬ」という結論を導くものです。

Prologでは、規則や事実を定義してから、クエリを与えることで、そのクエリに対する結果を得ることができます。この場合、クエリは「死ぬ(X)」という形をしており、Xには具体的な値が入ることになります。しかし、このコードの中では、クエリに具体的な値が与えられていないため、PrologはXを未定義のままとして扱い、「ソクラテスは死ぬ」という結論を導き出します。

さすがに完璧な回答です。ホントなんでも知ってるんですね。

規則:親子関係のルール


それではまず、さきの親子関係のルール「おかあさんのおかあさんはおばあちゃん」を教えて、回答できるかどうか試してみます:

規則:
おばあちゃん(G,X):-おかあさん(P,X),おかあさん(G,P).

事実:
おかあさん(なつこ,はるこ).
おかあさん(あきこ,なつこ).

質問:
おばあちゃん(X,はるこ).
X =
あきこ

正しい答えが返ってきました。

同じルールを使って、逆の関係も聞いてみます。「おばあちゃんがあきこの人はだれか?」ーーつまり「あきこの孫は?」、という質問です:

規則:
おばあちゃん(G,X):-おかあさん(P,X),おかあさん(G,P).

事実:
おかあさん(なつこ,はるこ).
おかあさん(あきこ,なつこ).

質問:
おばあちゃん(あきこ, X).
X =
はるこ

これも正解ですね。

次は規則を増やしてみましょう。ひいおばあちゃんの関係を追加してみます:

規則:
おばあちゃん(G,X):-おかあさん(P,X),おかあさん(G,P).
ひいおばあちゃん(H,X):-おばあちゃん(G,X),おかあさん(H,G).

事実:
おかあさん(なつこ,はるこ).
おかあさん(あきこ,なつこ).
おかあさん(ふゆこ,あきこ).

質問:
?- ひいおばあちゃん(X,はるこ).
X =
ひいおばあちゃん(X,はるこ)を満たすXを求めるためには、次のように推論します。

ひいおばあちゃん(H,はるこ):- おばあちゃん(G,はるこ), おかあさん(H,G).
おばあちゃん(G,はるこ):- おかあさん(P,はるこ), おかあさん(G,P).
おかあさん(なつこ,はるこ) が与えられているため、以下のように推論できます。

おかあさん(G,なつこ) :- おかあさん(P,はるこ), おかあさん(G,P).
おばあちゃん(G,はるこ) :- おかあさん(G,なつこ), おかあさん(なつこ,はるこ).
ひいおばあちゃん(H,はるこ) :- おばあちゃん(G,はるこ), おかあさん(H,G).

これらの推論から、ひいおばあちゃん(X,はるこ)を満たすXは、次のように求められます。

?- ひいおばあちゃん(X,はるこ).
X = ふゆこ.

いきなり解説を始めましたが、正解です。うまく論理を追えています。

それではもうすこしおおざっぱな問いーー孫と祖母の関係にあるのはだれか?、というのを聞いてみます:

規則:
おばあちゃん(G,X):-おかあさん(P,X),おかあさん(G,P).

事実:
おかあさん(なつこ,はるこ).
おかあさん(あきこ,なつこ).

質問:
おばあちゃん(X,Y).
X =
Y =
X = あきこ,
Y = はるこ.

これもうまく答えてくれました。

複数の事実がある場合はどうでしょうーー2コ目の親子関係を追加して、個別に答えられるかやってみます:

規則:
おばあちゃん(G,X):-おかあさん(P,X),おかあさん(G,P).

事実:
おかあさん(なつこ,はるこ).
おかあさん(あきこ,なつこ).
おかあさん(なびき,あかね).
おかあさん(かすみ,なびき).

質問:
おばあちゃん(X,Y).
X =
Y =
X = なつこ,
Y = あかね.

う〜ん……これくらい複雑になるとダメみたいですね、しかも無関係の家族に言及してしまってますし……

規則:さまざまなルール


ただ大規模言語モデルはそれなりに知識があるので、ほんとうにここで与えた規則だけを使って答えているのかどうか、怪しい部分もありますーーいちおう自然言語で、親子関係の質問をしてみましょう:[※1]

fact:
ちさと's mother is くるみ.
くるみ's mother is たきな.

show:
ちさと's grandmother is
たきな.

Since くるみ is the mother of ちさと and くるみ's mother is たきな, it follows that たきな is the grandmother of ちさと. Therefore, ちさと's grandmother is たきな.

どうやら、母と祖母の言葉の関係はすでに知っているようです……


※1
念のため、これまでに使っていない事実(しかもたぶんありそうもない事実)を使って、母〜祖母の関係を知っているかどうかを聞いています。また言語は英語にして、答えやすいようにしています。

日本語ではどうでしょうか:

事実:
ちさとの おかあさんは くるみ。
くるみの おかあさんは たきな。

質問:
ちさとの おばあちゃんは
与えられた事実からは、ちさとのおばあちゃんに関する情報は分かりません。

さすがに日本語の知識はそこまで深くないようです。とはいえ、論理式だと英語から類推できる、ということもあるかもしれません。

ということで、次はまったく未知の言葉を使って、これまでと同様の論理的な問いに答えられるか確かめてみます:

規則:
あいうえお(G,X):-かきくけこ(P,X),かきくけこ(G,P).

事実:
かきくけこ(らりる,やゆよ).
かきくけこ(わをん,らりる).

質問:
あいうえお(X,やゆよ).
X =
わをん

解説:

まず、与えられた規則は「GとXがあるとき、PとXがかきくけこであり、かきくけこにGとPが含まれる」という意味です。ここで「かきくけこ」というのは、あくまでも仮の関数名であり、具体的な意味はありません。

次に、与えられた事実は「らりるがやゆよであり、わをんがらりるである」という意味です。

最後に、質問されたのは「あいうえお(X,やゆよ)」ということで、つまりは「やゆよという引数を持つあいうえお(X,Y)という関数を評価した結果を求めよ」ということになります。

この場合、規則により「かきくけこ(わをん,らりる)」が成立しており、さらに「かきくけこ(らりる,やゆよ)」も成立しているため、結果として「あいうえお(X,やゆよ)」においてXは「わをん」という値になります。

お、正しい答えが返ってきますねーー純粋に示された規則から論理を追えているようです。

規則を増やしてみましょう:

規則:
あいうえお(G,X):-かきくけこ(P,X),かきくけこ(G,P).
さしすせそ(H,X):-あいうえお(G,X),かきくけこ(H,G).

事実:
かきくけこ(らりる,やゆよ).
かきくけこ(わをん,らりる).
かきくけこ(まみむ,わをん).

質問:
さしすせそ(X,やゆよ).
X =
まみむ

解説:

まず、質問のさしすせそ(X,やゆよ)に対して、事実のかきくけこの関係を使って、さしすせそ(H,X):-あいうえお(G,X),かきくけこ(H,G)の規則に当てはめます。

具体的には、かきくけこ(らりる,やゆよ)から、あいうえお(G,やゆよ), かきくけこ(H,らりる)を導きます。さらに、かきくけこ(わをん,らりる)から、あいうえお(G,らりる),かきくけこ(H,わをん)を導きます。最後に、かきくけこ(まみむ,わをん)から、あいうえお(G,わをん),かきくけこ(H,まみむ)を導きます。

ここで、質問のさしすせそ(X,やゆよ)に当てはめると、H=X, G=わをんとなります。そして、あいうえお(わをん,やゆよ)を使って、さしすせそ(X,やゆよ):-あいうえお(わをん,やゆよ),かきくけこ(X,わをん)を導くことができます。

したがって、X=まみむとなります。

合ってますーーいちおう提示された論理だけで答えられるようですーーこれなら親子関係だけでなく、ある程度かんたんなものなら、いろいろな規則をPrologで覚えさせられるかもしれません。

それではさらに、もうすこし高度な記号処理ができるかどうかもみてみましょうーーこれまではPrologの書式に沿って質問してきましたが、独自の書式でも対応できるでしょうか:

規則:
おばあちゃん[G,X]<-おかあさん[P,X],おかあさん[G,P];

事実:
おかあさん[なつこ,はるこ];
おかあさん[あきこ,なつこ];

質問:
おばあちゃん[X,はるこ];
X =
Xには、「あきこ」という値が入ります。

以下のように導出されます。

おかあさん[なつこ,はるこ]から、おばあちゃん[G,はるこ]を導出することができます。
規則に従って、おばあちゃん[G,X]<-おかあさん[P,X],おかあさん[G,P]から、おばあちゃん[X,はるこ]を導出することができます。
おかあさん[あきこ,なつこ]から、おばあちゃん[G,なつこ]を導出することができます。
規則に従って、おばあちゃん[G,X]<-おかあさん[P,X],おかあさん[G,P]から、おばあちゃん[X,なつこ]を導出することができます。

しかし、規則や事実に矛盾がある場合、この答えは変わる可能性があります。

おお、けっこう解釈できてますね……すごい。

会話


それではいよいよ、これが会話のメモリに使えるかどうか、やってみたいと思います。

会話は兄と妹のロールプレイとしますーーまずは、なんの知識も与えずにプロンプトを投入してみましょう:

兄と妹の会話です。妹は丁寧語を使いません。妹はひとことだけ答えます。
兄:はるこさんのおばあちゃんってだれだっけ?
妹:

結果は次のようになります(試みた回数:4回):

わかんない。
わからない。
わかんない。
わからない。

まあ知らないからとうぜんですね。

このロールプレイに、さきほどのルール(規則)とデータ(事実)を加えてやってみます:

規則:
おばあちゃん(G,X):-おかあさん(P,X),おかあさん(G,P).

事実:
おかあさん(なつこ,はるこ).
おかあさん(あきこ,なつこ).
おかあさん(なびき,あかね).
おかあさん(かすみ,なびき).

会話:
兄と妹の会話です。妹は丁寧語を使いません。妹はひとことだけ答えます。
兄:はるこさんのおばあちゃんってだれだっけ?
妹:

結果は、次のようになりました(試みた回数:4回):

はるこさんのおばあちゃんはなつこさんです。
はるこさんのおばあちゃんは、なつこさんのお母さんですよ。
はるこさんのおばあちゃんは、なつこさんのお母さんです。
はるこさんのおばあちゃんはなつこさんです。

う〜ん……打率5割というところでしょうか……しかも冗長ですし(「丁寧語を使わない」も無視されてますしね)。

べつの家族についても聞いてみましょう:

規則:
おばあちゃん(G,X):-おかあさん(P,X),おかあさん(G,P).

事実:
おかあさん(なつこ,はるこ).
おかあさん(あきこ,なつこ).
おかあさん(なびき,あかね).
おかあさん(かすみ,なびき).

会話:
兄と妹の会話です。妹は丁寧語を使いません。妹はひとことだけ答えます。
兄:あかねさんのおばあちゃんってだれだっけ?
妹:

結果は、次のようになりました(試みた回数:4回):

あかねさんのおばあちゃんはかすみさんだよ。
あかねさんのおばあちゃんは、かすみさんです。
あかねさんのおばあちゃんは、かすみさんです。
あかねさんのおばあちゃんは、かすみさんです。

こんどはぜんぶ合ってますねーー事実を記述する順序で、正答率は違ってくるのかな?

補足


ちなみに自然言語で、上のような規則と事実を記述して質問しても、ChatGPT はそれなりに回答します:

規則:
おかあさんの おかあさんは おばあちゃん。

事実:
はるこの おかあさんは なつこ。
なつこの おかあさんは あきこ。
あかねの おかあさんは なびき。
なびきの おかあさんは かすみ。

質問:
はるこの おばあちゃんは
……

英語の場合は、もともと<母〜祖母>の言葉の関係を知っているので、規則そのものがいらないかもしれませんが:

rule:
one person's mother's mother is the person's grandmother.

fact:
はるこ's mother is なつこ.
なつこ's mother is あきこ.
あかね's mother is なびき.
なびき's mother is かすみ.

show:
はるこ's grandmother is
……

ただこの場合、自然言語でルールを記述すると、家族関係にないものを回答することがままある、という問題がありますーーその点、(Prologのように)ルールが構造化されていれば、ほぼ家族関係のあるものしか回答しないようですし。

もちろん構成を工夫すれば、それなりに成果は上げられるはずですーーただ、プロンプトはできるだけ簡潔にしたい(=コストは抑えたい)というのもあり、バランスが難しいところですね。