Recursion 给出奇数结果的成员函数。

Recursion 给出奇数结果的成员函数。,recursion,prolog,Recursion,Prolog,我编写了一个成员函数,用于检查列表中是否存在元素 member(X, [X|_]). member(X, [_|Y]) :- member(X, Y). 我将.pl文件加载到SWI prolog中,没有收到与成员相关的警告或错误。我使用 member(A, [1,2,3,4]). 这,显然应该返回false。相反,我得到了 A = 1 然后,当我尝试输入新命令时,ide只显示我键入的键,并显示未知操作“我按过的键” 我认为我的成员函数是合理的,因为它与我的教授编写的函数相匹配 有什么想法

我编写了一个成员函数,用于检查列表中是否存在元素

member(X, [X|_]).
member(X, [_|Y]) :- member(X, Y).
我将.pl文件加载到SWI prolog中,没有收到与成员相关的警告或错误。我使用

member(A, [1,2,3,4]).
这,显然应该返回false。相反,我得到了

 A = 1
然后,当我尝试输入新命令时,ide只显示我键入的键,并显示未知操作“我按过的键”

我认为我的成员函数是合理的,因为它与我的教授编写的函数相匹配


有什么想法吗?

您在i/o模式(o,i)中调用了谓词
成员/2
,即第一个参数为自由(未绑定)变量,第二个为绑定变量

在这种模式下(尽管名称不同)
member/2
实际上并不针对列表成员身份测试元素,而是简单地逐个枚举列表元素,最后,当没有元素保留时,它会失败(谓词fail在逻辑编程方面,而不是返回false

该谓词通常用于所谓的故障驱动控制技术,例如:

简单编写枚举列表元素时的一个简单示例

 ?- forall( member(X, [1,2,3,4]), write( X ) ).
注意,在这种情况下,列表用尽后不会出现故障。 为了确保这一点,添加了最后一个子句,意思是“谓词完全成功”


您已经在i/o模式(o,i)e.i.中调用了谓词
member/2
。第一个参数是自由(未绑定)变量,第二个是绑定变量

在这种模式下(尽管名称不同)
member/2
实际上并不针对列表成员身份测试元素,而是简单地逐个枚举列表元素,最后,当没有元素保留时,它会失败(谓词fail在逻辑编程方面,而不是返回false

该谓词通常用于所谓的故障驱动控制技术,例如:

简单编写枚举列表元素时的一个简单示例

 ?- forall( member(X, [1,2,3,4]), write( X ) ).
注意,在这种情况下,列表用尽后不会出现故障。 为了确保这一点,添加了最后一个子句,意思是“谓词完全成功”


为什么
成员(A[1,2,3,4])
显然应该返回false?显然,对于
A=1
以及
A=2
A=3
A=4
,它应该会成功。当显示
A=1
时,您需要按空格键或
查看下一个结果,如果有(根据Prolog文档)。很可能这个谓词不是你的教授写的
member/2
,我想这种实现已经存在了几十年了?我在1986年出版的一本枯树教材中看到过它,但我想它比这本书早。@Boris:
member/2
成为真正的内置软件是最近的~不到10年。因此,提供其定义是很自然的。@false在SWI Prolog中,它不是真正的内置函数,而是在库中定义的。我想YAP也是这样。我不知道GNU Prolog的实现,但在那里它应该不重要,对吗?不过,我的观点是,这个定义已经存在了很长一段时间。@Boris:在SWI中,您仍然可以添加自己对
member/2
的定义,如
member(1,2)。
但是,一旦您使用隐式定义的版本,您就无法使用它。它是SICStus 4中的内置(您无法重新定义)。在YAP中,它根本没有定义(至少在我尝试的版本中,YAP最近有一些奇怪的变化,这使得它很难遵循)。在GNU中,它不能被重新定义。无论如何,至少序言提供了第一个。为什么
成员(A[1,2,3,4])
显然应该返回false?显然,对于
A=1
以及
A=2
A=3
A=4
,它应该会成功。当显示
A=1
时,您需要按空格键或
查看下一个结果,如果有(根据Prolog文档)。很可能这个谓词不是你的教授写的
member/2
,我想这种实现已经存在了几十年了?我在1986年出版的一本枯树教材中看到过它,但我想它比这本书早。@Boris:
member/2
成为真正的内置软件是最近的~不到10年。因此,提供其定义是很自然的。@false在SWI Prolog中,它不是真正的内置函数,而是在库中定义的。我想YAP也是这样。我不知道GNU Prolog的实现,但在那里它应该不重要,对吗?不过,我的观点是,这个定义已经存在了很长一段时间。@Boris:在SWI中,您仍然可以添加自己对
member/2
的定义,如
member(1,2)。
但是,一旦您使用隐式定义的版本,您就无法使用它。它是SICStus 4中的内置(您无法重新定义)。在YAP中,它根本没有定义(至少在我尝试的版本中,YAP最近有一些奇怪的变化,这使得它很难遵循)。在GNU中,它不能被重新定义。无论如何,至少序言提供了第一个。提交给
member/2
的文档通常非常(也?)简洁,例如,请参见:“当
Elem
列表的成员时为True”。当
Elem
是一个变量时,“是成员”转换为“与成员统一”。我指出这一点只是为了说明,
member/2
的实现或文档中没有任何内容声称它只测试基本元素是否在基本列表中。同意。我的意思只是(以我个人的经验)member/2由于其典型用法(X是Xs的成员)可能会被从侧面解释。我不会真正将
member(A[1,2,3,4])
作为一种操作模式。在Prolog中,查询是一个查询,Prolog只是尝试使该查询成功,并将实例化任何变量(如果可以的话),以获得成功。查询
成员(1[1,2,3,4])