5

手動で作成したDCGルールを使用して、1つの単語よりも慣用句を選択します。DCGルールは次のようになります。

seq(cons(X,Y), I, O) :- noun(X, I, H), seq(Y, H, O), \+ noun(_, I, O).
seq(X) --> noun(X).

(:-)/2の代わりにが使用されるため、最初の句は手動で作成され(-->)/2ます。この手動で作成された句を、標準のDCGを使用する句に置き換えることはできますか?

よろしくお願いします

PS:ここにいくつかのテストデータがあります:

noun(n1) --> ['trojan'].
noun(n2) --> ['horse'].
noun(n3) --> ['trojan', 'horse'].
noun(n4) --> ['war'].

そして、ここにいくつかのテストケースがあります。重要なテストケースは最初のテストケースです。これは、n3のみを提供し、cons(n1、n2)は提供しないためです。最初のテストケースの動作は、特に望ましいものです。

?- phrase(seq(X),['trojan','horse']).
X = n3 ;
No
?- phrase(seq(X),['war','horse']).
X = cons(n4,n2) ;
No
?- phrase(seq(X),['trojan','war']).
X = cons(n1,n4) ;
No
4

1 に答える 1

5

(他の非終端記号との衝突を避けるために、名前をに変更seq//1しましたnounseq//1

この手動で作成された句を、標準のDCGを使用する句に置き換えることはできますか?

いいえ、それは不動ではなく、STOであるためです(詳細は以下を参照)。

意図された意味

しかし、あなたのプログラムの意図された意味から始めましょう。単一の単語よりも慣用句を選択したいとします。あなたのプログラムは本当にこれをやっていますか?または、言い換えると、あなたの定義は本当にユニークですか?これで反例を作成できましたが、Prologに考えさせてください。

名詞->[]| 名詞(_)、名詞。

?-長さ(Ph、N)、フレーズ(名詞、Ph)、
   dif(X、Y)、phrase(nounseq(X)、Ph)、phrase(nounseq(Y)、Ph)。
Ph = [トロイの木馬、馬、トロイの木馬]、
N = 3、
X = cons(n1、cons(n2、n1))、
Y = cons(n3、n1);
...;
Ph = [トロイの木馬、馬、戦争]、
N = 3、
X = cons(n3、n4)、
Y = cons(n1、cons(n2、n4))..。

したがって、あなたの定義はあいまいです。本質的に必要なのは(おそらく)ある種の書き換えシステムです。しかし、それらが明確な方法で定義されることはめったにありません。どう、2つの単語が追加のように重なっている場合noun(n5) --> [horse, war].など。


適合性

事前の免責事項:現在、DCGドキュメントはまだ作成中です—そしてコメントは大歓迎です!あなたはこの場所ですべての資料を見つけます。厳密に言えば、現時点ではDCGへの適合の概念はありません。

安定性

適合定義が維持しなければならない1つの中心的な特性は、不動性の特性です。したがって、定義を検討する前に、phrase/3(デフォルトモードでSWIを実行する)の2つの目標を比較します。

?-Ph = []、phrase(nounseq(cons(n4、n4))、Ph0、Ph)。
Ph = []、
Ph0 = [戦争、戦争];
false。

?-phrase(nounseq(cons(n4、n4))、Ph0、Ph)、Ph=[]。
false。

?-phrase(nounseq(cons(n4、n4))、Ph0、Ph)。
false

最後にゴールPh = []を移動すると、唯一の解決策が削除されます。したがって、あなたの定義は確固たるものではありません。これは、処理方法によるものです(\+)/1。変数は。O内で発生してはなりません(\+)/1。しかし一方で、それが内部で発生しない場合(\+)/1は、文の先頭のみを検査できます。そして、文全体ではありません。

発生する可能性があります-プロパティを確認してください

しかし、状況はさらに悪化します。

?-set_prolog_flag(occurs_check、error)。
本当。

?-phrase(nounseq(cons(n4、n4))、Ph0、Ph)。
エラー:名詞/ 3:_G968を[war | _G968]と統合できません:無限ツリーが作成されます

したがって、プログラムはSTO統合(subject-to-occurs-check統一)に依存しており、その結果はで明示的に定義されていません。

ISO / IEC 13211-1 7.3.3節発生-チェック(STO)の対象であり、発生-チェック(NSTO)の対象ではない

これは、2つの非終端記号の交差を定義するという意図によるものです。それを表現する次の方法を検討してください。

:-op(950、xfx、// \\)。∩-2229;INTERSECTIONの%ASCII近似

(NT1 // \\ NT2)->
     call(Xs0 ^ Xs ^(phrase(NT1、Xs0、Xs)、phrase(NT2、Xs0、Xs)))。

%以下はで事前定義されていlibrary(lambda)ます:

^(V0、目標、V0、V):-
      call(Goal、V)。

^(V、ゴール、V):-
     call(ゴール)。

すでにこの定義で、STOの状況に入ることができます。

?-フレーズ(([a] // \\ [a、b])、Ph0、Ph)。
エラー:=/ 2:_G3449を[b | _G3449]と統合できません:無限ツリーが作成されます

実際、有理木を使用すると、次のようになります。

?-set_prolog_flag(occurs_check、false)。
本当。

?-フレーズ(([a] // \\ [a、b])、Ph0、Ph)。
Ph0 = [a | _S1]、%ここで
    _S1 = [b | _S1]、
Ph = [b|_S1]。

したがって、自然言語の文には確かにあまり意味がない無限のリストがあります(無限のリソースと容量の人を除いて...)。

于 2012-12-09T15:19:43.030 に答える