2

Prolog でいくつかのルールを実装する必要があります

元:

S ---> A,[b],{c}.

どこ:

[b] 0 回または 1 回のように、1 回またはまったく発生しない可能性があります

{c} は 0、1、2、... 回発生する可能性があります

どうすれば書けるでしょうか?

編集:

私はこれを使用しました:

:- op(700,xfx,--->).
s ---> [vp].
s ---> [vp,conj,vp].
s ---> [vp,conj,np].
vp ---> [feal_amr],
        ([mfoal_beh];[]),
        ([mfoal_beh];[]),
        ([bdl];[]),
        [sefa_optional],
        ([hal];[]),
        ([shbh_gomla];[]),
        ([mfoal_motlk];[]).

「句本体で完全に停止しますか?再定義できません,/2」というエラーが表示されます

この行のコンマに「vp ---> [feal_amr], ...」

編集

私はこれを持っているので、「--->」を使用します

parse_topdown(Category,String,Reststring,[Category|Subtrees]) :-
        Category ---> RHS,
        matches(RHS,String,Reststring,Subtrees).

そして、「-->」は演算子「:-」でエラーになります?!!

これは、 アラビア語パーサー コードの私のコードです

ご不便をおかけして申し訳ありませんが、私は Prolog の専門家ではありません。

4

2 に答える 2

1

まず、おそらく小文字のSとAが必要です。Prologは変数名に初期キャップを使用します。

'b'が1回発生するか、まったく発生しないようにする1つの方法は、次のように記述することです。

s --> a, b_optional, {c}.

b_optional --> [b].
b_optional --> [].

必要に応じて、b_optionalの2つのルールを1つのルールとして記述するための構文もあります。お気に入りのPrologテキストの明確な句の文法に関する章を参照してください。

私はあなたが0、1、2、...回起こっていることの意味がわからないので、私はそこであなたを助けることができないと思います。

于 2012-12-15T20:58:10.913 に答える
1

あなたの説明から

s --> [a], ([b] ; []), c_1.
c_1 --> [c], c_1 ; [].

いくつかのテスト パターン:

?- phrase(s, [a,b,c,c,c]).
true

?- phrase(s, [a]).
true

編集

コードについて: を使用する必要があります-->。なぜ宣言する--->(そして定義しない)のですか?そうすれば、独自のアナライザーを作成する必要があり、DCG を使用していません。

[vp,conj,vp] は端末のリストであることに注意してください。

feal_amr、mfoal_beh などについては不明ですが、vp 確かに非終端記号です (書き直されています)。

それなら書いた方がいいと思う

s --> vp.
s --> vp,conj,vp.
s --> vp,conj,np.

vp -->
  [feal_amr],
  ([mfoal_beh];[]),
  ([mfoal_beh];[]),
  ([bdl];[]),
  [sefa_optional],
  ([hal];[]),
  ([shbh_gomla];[]),
  ([mfoal_motlk];[]).

% I hypotesize it's a comma.
conj --> [','].

コメントに記載されているように編集します。DCG を使用していませんが、独自のインタープリターを使用しています。最小限の例でテストしました

:- op(700,xfx,--->).

s ---> [name,verb,names].

names ---> [name, conj, names].
names ---> [name].
names ---> [].

lex(anne, name).
lex(bob, name).
lex(charlie, name).

lex(call, verb).
lex(and, conj).

parse_topdown(Category,[Word|Reststring],Reststring,[Category,Word]) :-
        lex(Word,Category).

parse_topdown(Category,String,Reststring,[Category|Subtrees]) :-
        Category ---> RHS,
        matches(RHS,String,Reststring,Subtrees).

matches([],String,String,[]).
matches([Category|Categories],String,RestString,[Subtree|Subtrees]) :-
        parse_topdown(Category,String,String1,Subtree),
        matches(Categories,String1,RestString,Subtrees).

このプログラムは、0、1、またはそれ以上の名前を受け入れます。

?- parse_topdown(s,[anne,call,bob,and,charlie],R,P).
R = [],
P = [s, [name, anne], [verb, call], [names, [name, bob], [conj, and], [names|...]]] ;
R = [charlie],
P = [s, [name, anne], [verb, call], [names, [name, bob], [conj, and], [names]]] ;
R = [and, charlie],
P = [s, [name, anne], [verb, call], [names, [name, bob]]] ;
R = [bob, and, charlie],
P = [s, [name, anne], [verb, call], [names]] ;
false.

注: 部分一致を調べるために、R はそのままにしておきます。元の質問に戻ると、非終端記号がnames0、1、または多くの ( で区切られたand) 値をどのように受け入れるかがわかります。

このようなインタープリターは、実質的な入力では非常に遅くなることに注意してください。DCG を使用して文法を書き直すことをお勧めします。

于 2012-12-15T22:05:18.513 に答える