List 此程序的声明性解释,说明元素是否属于列表

List 此程序的声明性解释,说明元素是否属于列表,list,prolog,declarative,List,Prolog,Declarative,从我的理解来看,陈述式范式表明了什么是达成解决方案的重要因素,而不是如何达成解决方案,但是,由于习惯于按程序思考,我经常会产生困惑 因此,解决方案是: mymember(X, [X|_]). mymember(X,[_|T]) :- mymember(X,T). 这是我对这个简单程序的声明性解释: 1) 如果X确实是该列表的头,则X属于该列表(如果列表的头元素与我知道是否在列表中的X元素相结合) 2) 如果第一个事实不正确(X与第一个列表元素不一致),程序将尝试执行第二条规则(这里可能有一些解

从我的理解来看,陈述式范式表明了什么是达成解决方案的重要因素,而不是如何达成解决方案,但是,由于习惯于按程序思考,我经常会产生困惑

因此,解决方案是:

mymember(X, [X|_]).
mymember(X,[_|T]) :- mymember(X,T).
这是我对这个简单程序的声明性解释:

1) 如果X确实是该列表的头,则X属于该列表(如果列表的头元素与我知道是否在列表中的X元素相结合)

2) 如果第一个事实不正确(X与第一个列表元素不一致),程序将尝试执行第二条规则(这里可能有一些解释问题)。这条规则说:如果规则的主体是真的,那么头部是真的)

规则的负责人说:X属于列表的尾部(我使用一个匿名变量,使用\uu字符表示不关心列表的第一个元素)

所以这个规则说:如果X元素确实属于列表的尾部,那么X元素确实属于没有头部的列表

这是对这个程序的正确的声明性和逻辑解释,还是我遗漏了什么?

你把它们理解为排他或,但实际上它们是包含或。1)和2)都正确,减去连接词“如果第一个事实不正确”。没有必要1)为假2)为保持。换言之,
X
确实是列表的头部,并且出现在列表的尾部(例如
mymember(a[a,b,a])

编辑:回复您的评论

这里有一个语言障碍的问题,所以让我试着用是和否来回答你的问题

是的,使用
生成另一个答案是Prolog能够计算替代答案的证据。从某种意义上说,
手动触发回溯,但从另一种意义上说,是Prolog询问您这是否是您想要的答案,然后您可以说“是”或“否”当你说
时,本质上你是在告诉Prolog,“这不是正确的答案。”但这不是触发回溯的唯一方法;事实上,大多数时候你根本不会手动触发它

例如,让我们看看这个:

even_member(X, L) :- member(X, L), 0 is X mod 2.

?- even_member(X, [1,5,17,23,4,19]).
X = 4 ;
false.
所以这里我定义了一个谓词,声明性地说,如果X是L的成员,X mod 2=0,那么X是L的偶数成员。当我使用谓词时,我们得到了答案
X=4
。然后我们按
说,这不是正确的答案,Prolog说没有更多的答案。但是在内部,成员(X,L)在找到满足谓词第二部分的元素之前回溯了5次——换句话说,语句
0 is X mod 2
告诉Prolog 1、5、17和23是“错误的”当我们说需要另一个答案时,我们使用了相同的机制,所以Prolog回到成员(X,L),找到19,然后发现19不能被2整除,于是放弃了

Prolog回溯了六次,其中五次只是为了得到一个答案。我们只要求它回溯一次,碰巧这是最后一次,所以它没有再回溯。

第2点)不成立:Prolog将尝试每个规则来搜索解决方案

但它将遵循数据库中严格指定的顺序搜索,从而对解决方案空间进行深度优先搜索

我会读书

如果X是第一个元素(即统一头部,第1条),或者是尾部的成员(第2条),则X是列表的成员。

让我试试:

mymember(X, [X|_]).
如果X是列表的第一个元素,则它是列表的成员

mymember(X,[_|T]) :- mymember(X,T).
如果X是列表其余部分的成员,则它是列表的成员

假设我给你一堆(纸质)程序员简历,并说“看看这些简历中是否有一个程序员懂Prolog”

你是做什么的?你看上面的简历。如果那个程序员懂Prolog,你就完了


如果没有,那么只有在剩下的堆栈中才能有这样一份简历

好的,如果我有类似于mymember(a,[a,b,a])的东西,我必须使用;在Prolog控制台中的角色来执行回溯和探索计算的另一个分支…这是真的吗?这就是你的意思吗?我们在答案中添加了一些讨论。如果还不清楚,请告诉我。