3

SWIPrologで否定を使用することについて奇妙な質問があります。否定"\+"の後にスペースを入れずに次のコードを使用すると、エラーが発生します。

2 ?- assert((only_child(X) :- mother(M,X),\+(mother(M,_),\+ X==_))).
true.

3 ?- only_child(cathy).
ERROR: only_child/1: Undefined procedure: (\+)/2
ERROR:   However, there are definitions for:
ERROR:         (\+)/1
Exception: (7) \+(mother(melody, _G2102), \+cathy==_G2107) ? creep
4 ?-

ただし、否定後にスペースを使用すると、完全に正常に機能します。

2 ?- assert((only_child(X) :- mother(M,X),\+ (mother(M,_),\+ X==_))).
true.

3 ?- only_child(cathy).
false.

4 ?-

ただし、次のコードは、「\+」の後にスペースを使用する場合とスペースを使用しない場合の両方で正常に機能します。

4 ?- \+ father(michael,cathy).
false.

5 ?- \+father(michael,cathy).
false.

6 ?-

誰かが私にこれを説明できますか?その本当に非常に不可解です。本当にありがたいです。

4

3 に答える 3

3

Prologには、演算子と括弧の間にスペース(「区切り文字」)が必要です。

スペースがない場合、Prologパーサーはそれを2つのパラメーターを持つファンクターとして扱います。以下の2つのケースは、パーサーと同じです。

mother(..., ...)
\+(..., ...)

ただし、スペースを入れると、パーサーはそれを演算子および括弧で囲まれた引数として扱います。逆のルールがあり(ファンクターの名前と括弧の間にスペースがあってはなりません)、この行を作成するとエラーも発生します。

mother (..., ...)

経験則では、演算子の場合は、後ろにスペースを入れます。

于 2012-10-17T23:53:25.740 に答える
3

Prologを解析する場合、開き括弧は特別です。識別子と開始親の間にスペースがない場合、識別子は常にファンクタの名前として扱われます(英数字でない場合でも)。パレンの中にあるものはすべて、このファンクターの引数のリストとして扱われます。

ただし、スペースがある場合、パレンは式をグループ化する通常の数学関数で扱われます。andこのような式の中のコンマは、ブール演算子の役割を果たします。

それで:

"func(A,B)"  - OK - invoke `func` on parameters `A`, `B`    
"func (A,B)" - syntax error - interpreted as an identifier stuck together 
               with an AND expression    
"\+ (A,B)"   - OK - operator `\+` acting on `(A,B)` (A and B)    
"\+(A,B)"    - error - invoke `\+` with two parameters `A`, `B` 
               but \+ only takes one argument    
"\+(A)"      - OK - since `\+` takes one argument, it can 
               be invoked as a functor with one argument inside parens

パーサーは、演算子を識別子から分割するのに十分インテリジェントです(最初の文字が新しいトークンをトリガーします)。

"\+ father(A,B)" - OK - invoke functor `father` with `A` and `B`, 
                   negate the result
"\+father(A,B)"  - still OK - the parser will stop reading the 
                   name of the operator when it encounters the 'f', 
                   so the result is same as above
于 2012-10-18T15:04:40.330 に答える
2

Prologはファンクターと引数の間にスペースを入れないという説明が必要だと思います。

演算子は、適切な宣言を持つファンクターです(op /3およびcurrent_op /3を参照)。このような宣言の後、ファンクターを演算子として使用するかどうかを選択できます。算術演算を使用した不自然な例:

?- X is +(1,*(5,8)).
X = 41.

?- X is 1+5*8.
X = 41.

?- X is 1+(5*8).
X = 41.

次に、表示されたエラーはこれに似ています

?- X is + (1,*(5,8)).
ERROR: evaluable `1,5*8' does not exist
   Exception: (6) expand_goal(_G209 is + (1, 5*8), _G292, user, [user, system], _G295) ? creep

つまり、+ファンクターとして使用されるアトムでは、括弧の前にスペースを入れることはできません。

編集 もう1つの注目すべき点は,、演算子として宣言されていることです。これは、を意味ANDします、引数の区切り文字として使用される語彙要素でもあります。次に、2番目のケースでは、接続詞に+が適用されますmother(M,_) AND \+ X==_

于 2012-10-18T06:03:32.137 に答える