2017-04-14 31 views
1

我写了一个成员函数来检查一个元素是否存在于一个列表中。成员函数给出奇怪的结果。

member(X, [X|_]). 
member(X, [_|Y]) :- member(X, Y). 

我将.pl文件加载到SWI prolog中,并且我没有收到有关成员的警告或错误。我测试成员函数使用...

member(A, [1,2,3,4]). 

这,显然应该返回false。相反,我得到

A = 1 

然后,当我试图进入新的命令时,IDE只是表明我,我输入的钥匙,并说不明行动“什么都键I按下”

我觉得我的成员函数声音,因为它与我的教授写的相匹配。

任何想法?

+2

为什么'member(A,[1,2,3,4])*显然返回false *?对于A = 1和A = 2,A = 3和A = 4,显然应该是成功的。当它显示“A = 1”时,如果有(根据Prolog文档),您需要按SPACE或';'查看下一个结果。 – lurker

+1

可能性是,这个谓词不是由你的教授写的。 'member/2',这个实现,已经存在几十年了,我想呢?我在1986年出版的死树教科书中看到过它,但我猜它早于这本书。 – 2017-04-15 08:08:40

+0

@Boris:最近〜不到10年,'member/2'成了一个真正的内置。所以提供它的定义是很自然的。 – false

回答

0

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

在这种模式下(尽管它的名字)member/2其实并不对测试列表成员元素只是简单列举列表元素一个接一个,最后,当没有元素被保留,它失败(谓词在失败条款逻辑编程,而不是返回false)。

该断言经常在所谓的故障驱动的控制技术使用,例如:

当枚举列表元素被简单地写

?- forall(member(X, [1,2,3,4]), write(X)). 

注意,在这种情况下将不发生故障后

简单的例子列表已用尽。 为了确保这一点,添加了最后一个子句,这意味着“谓词成功”。

p(List, Action) :- generator(Variant, List), side_effect_action(Variant), fail. 
p(_ , _). 

generator(X, L) :- member(X, L). 
+0

”member/2“的文档通常很?)缓慢,参见例如[SWI-Prolog手册](http://eu.swi-prolog.org/pldoc/doc_for?object=member/2):“True w母鸡'Elem'是'List'的成员。“当Elem是一个变量时,“是一个成员”翻译为“与成员相结合”。我指出这一点只是为了说明“member/2”的实现或文档中没有任何内容声明它只是测试地面元素是否在地面列表中。 – 2017-04-15 09:06:55

+0

同意。我只是(由我的个人经验)指出,由于它的典型用法(X是X的成员),成员/ 2可能会被忽视。 –

+0

通常情况下,如果您想测试地面列表中的地面元素的成员资格,您可以使用“memberchk/2”,因为它更高效并且不会有选择点。 **不能被** memberchk/2替换的'member/2'的所有用法涉及**不是**的第一个参数;例如'? - member(a(X),[a(1),b(2),a(3)])''。 – 2017-04-15 09:50:56