Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog语法问题,否定后空格_Prolog - Fatal编程技术网

Prolog语法问题,否定后空格

Prolog语法问题,否定后空格,prolog,Prolog,在SWI Prolog中使用否定有一个奇怪的问题。当我使用以下代码时,在求反“\+”后没有空格,它会给出一个错误: 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

在SWI Prolog中使用否定有一个奇怪的问题。当我使用以下代码时,在求反“\+”后没有空格,它会给出一个错误:

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 ?-
mother (..., ...)
然而,如果我在否定之后使用空格,它的效果非常好

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 ?-
谁能给我解释一下吗?这真的很令人费解。我会非常感激的。

在操作符和括号之间加上空格(“分隔符”)

如果没有空格,Prolog解析器将其视为具有两个参数的函子。下面的两种情况与解析器没有什么不同

mother(..., ...)
\+(..., ...)
但是,如果放置一个空格,解析器将其视为运算符和括号内的参数。有一个相反的规则(函子名称和括号之间不能有空格),使得此行也产生错误:

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 ?-
mother (..., ...)

经验法则是——如果它是一个运算符,在它后面加一个空格。

我认为应该解释为Prolog不允许在函子和参数之间加空格

运算符是具有适当声明的函子(请参见/3和/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
i、 用作函子的原子
+
在括号前不允许有空格

编辑
另一件值得注意的事情是,
被声明为操作符,意思是
,但也是一个词汇元素,用作参数分隔符。然后,在第二种情况下,+应用于连词
母词(M,u)和\+X==
在解析Prolog时,左括号是特殊的。如果标识符和起始参数之间没有空格,则该标识符始终被视为函子的名称(即使它不是字母数字)。parens中的任何内容都被视为此函子的参数列表

然而,如果有一个空间,paren将在其正常的分组表达式的数学函数中处理。此类表达式中的逗号充当布尔
运算符

因此:

解析器还具有足够的智能,可以从标识符中拆分运算符(第一个字母触发一个新标记):


谢谢你的回复。我明白你说的话。但是在上面的例子中,当我不使用空格\+(母亲(…,…),\+X===\)时,解析器仍然应该将\+视为一个带有我提供给它的两个参数的函子。如果我错了,请纠正我。我的意思是,我已经为\+(mother(),\+X===\)提供了两个参数,mother()和\+X==\,因此解析器在没有空格的情况下仍然应该将\+视为具有两个参数的有效函子。我哪里错了,请纠正我。错误消息显示的内容证实了Jakub告诉您的,没有以下空格的解析器将\+视为要求应用该函子,将其视为有两个参数。虽然语法是“有效的”,但谓词\+(2)没有定义。默认情况下,SWI Prolog会主动将此标记为错误,而不仅仅是默默失败。但是,如果您更喜欢后者,SWI Prolog中有一个选项可以抑制“错误”。我想我有时会将嵌套括号加倍,而不是使用空格;“你试过了吗?”hardmath谢谢你的回答。然而,我仍然不明白的是(这也是我问题的第二部分),为什么解析器没有在\+父(michael,cathy)上给出错误。这里也没有空间,也没有父亲的定义。另外,请注意,错误消息包括“有以下定义:(\+)/1”。请帮我澄清一下。还感谢双参数的建议,是的,它起作用了。运算符后面的任何字符对于解析器都可以,除了开头参数。如果它是
\+父(…
,它知道运算符名称以“f”结尾。如果它是
\+(…
,它将
\+
视为函子的名称,实际上,只要只有一个东西(没有逗号),就可以像
\+(某物)
一样使用否定在parens内部。感谢您的解释。但是在第一种情况下,解析器将\+作为运算符(如果使用空格编写)和函子(如果使用空格编写)并给出一个错误,因为它没有定义。但在第二种情况下,当有空格时,它将\+作为运算符,如果没有空格时,它将\+作为函子写入,但仍然不会给出错误,即使函子在这里也没有定义,就像在前一种情况下一样。当这两种情况相似时,为什么它会区别对待?我无法理解还有这个。如果我错了,请纠正我。好吧,我更糊涂了。否定运算符
\+
不是作为一个整体来考虑的,还是它是
`和
+'的组合在一起工作的呢?还有,如果是你说的情况,它需要
作为and(实际上是根据谓词子句)为什么它会打印一个错误,说“Undefined procedure:(\+)/2”?这难道不意味着解析器将
作为参数分隔符吗?逗号有两个不同的用途,它的解析依赖于上下文(我想…)。非常感谢您如此清晰的解释。这确实消除了我的疑问。