プロが教える店舗&オフィスのセキュリティ対策術

 Prologについて質問があります。

 私は今Prologで簡易和英・英和翻訳機をつくろうとしているのですが、途中でつまづいています。

 以下のようなPrologリストを読み込んで、``in rooms''を日本語に直そうとして
   :-prep_phrase([in,rooms], [], B, []).
と入力すると、
   B = [heya,no,naka,no]
と正しい答が返ってきますが、逆に``heya no naka no''を英語に直そうと
   :-prep_phrase(A, [], [heya,no,naka,no], []).
と入力しても、無限ループに陥ってしまうようでエラーメッセージとして
   ``stack overflow''
が返ってきます。

 トレースしてみたところ、noun_phrase と prep_phrase が交互に次々と呼ばれていました。

 どうしてこのようなことが起こるのでしょうか(英->和はできているのに)。また、これを回避する方法はあるのでしょうか。


%% プログラムリストここから

%% 英語の「名詞+前置詞節」を日本語の「前置詞節+名詞」に
%% 翻訳する
%% ex. in rooms -> heya no naka no

%% 名詞節
noun_phrase(A, C, X, Z):-noun(A, B, Y, Z), prep_phrase(B, C, X, Y).

%% 前置詞節
prep_phrase(A, C, X, Z):-prep(A, B, Y, [no|Z]), noun_phrase(B, C, X, [no|Y]).
prep_phrase(A, A, X, X).

%% 前置詞
prep([in|A], A, [naka|X], X).

%% 名詞
noun([rooms|A], A, [heya|X], X).

%% プログラムリストここまで

A 回答 (2件)

この例だと、第1引数が不定の場合はひたすらリストに単語を追加して行くと


いう動作をすると思います。

prep_phrase(A,[],[heya,no,naka,no],[])
prep([in|A],A,[naka|[no|[]]],[no|[]])
noun_phrase(A,[],[heya,no,naka,no],[no|[naka|[no[]]]])
noun([rooms|B],B,[heya,no,naka,no],[no,naka,no])
prep_phrase(B,[],[heya,no,naka,no],[heya,no,naka,no])
prep([in|A],A,[naka,no,heya,no,naka,no],[no,heya,no,naka,no])

このあと、nounはarg1,arg2ともに単語をリストの先頭に単語を追加するだけ
なので成功します。その後再帰的にprep_phraseを呼び出しているのですが、
すでに、第1引数不定なのでリストは決して[]になりません...ので
停止条件が満たされること無く無限ループになります。(^_^;

# いまだに、ぷろろーぐってのこってるんだ...なつかしい...

この回答への補足

 回答ありがとうございます。

 この場合、何かこれを回避する方法などあるのでしょうか。それとも、規則を書き換えないといけないのでしょうか。

補足日時:2001/05/15 16:08
    • good
    • 0

根本的に述語の記述をもう少し整理したほうが良いとは思うのですが、


対処療法としては、

> prep_phrase(A, C, X, Z):-prep(A, B, Y, [no|Z]), noun_phrase(B, C, X, [no|Y]).
> prep_phrase(A, A, X, X).

の部分を

prep_phrase([],[],X,X).
prep_phrase(A, C, X, Z):-prep(A, B, Y, [no|Z]), noun_phrase(B, C, X, [no|Y]).

としたら止まりませんか?ちょっともう手元で処理系を使える環境に
いないので確認はできません。ごめん。

# 昔はメモリーも少なかったんで、
#
# 適宜 ! を使って不要なスタックをつぶす。
# unboundな変数は述語の最後の方の引数にすると良い。
# 可能なかぎりtail recursionを使う...
# list よりは 述語を使う等。
#
# とかしてたような...15年は昔の記憶なので間違ってる所が
# あってもかんべんしてください。(-_^;
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!