List Prolog谓词,用于显示处于偶数位置的列表的每个成员
我正在用Prolog研究逻辑编程的这个新概念。我曾经处理过切割、失败,现在我的话题是列表。我有以下任务要做: -编写一个函数List Prolog谓词,用于显示处于偶数位置的列表的每个成员,list,recursion,prolog,List,Recursion,Prolog,我正在用Prolog研究逻辑编程的这个新概念。我曾经处理过切割、失败,现在我的话题是列表。我有以下任务要做: -编写一个函数evenmember(元素,列表),它将显示元素在列表中是否处于偶数位置。例如,evenmember(X[1,5,3,2])将连续显示解决方案X=5,X=2 我已经玩了一段时间,写了以下内容: evenmember(_, []) :- !, fail. evenmember(_, [_]) :- !, fail. evenmember(X, [_, X]) :- !
evenmember(元素,列表)
,它将显示元素在列表中是否处于偶数位置。例如,evenmember(X[1,5,3,2])
将连续显示解决方案X=5,X=2
我已经玩了一段时间,写了以下内容:
evenmember(_, []) :- !, fail.
evenmember(_, [_]) :- !, fail.
evenmember(X, [_, X]) :- !.
evenmember(Elem, List):-
[_, Elem1|Tail] = List,
Elem is Elem1,
evenmember(Elem1, Tail).
显示对我有效的结果的唯一方法是引入write函数,但它对任务不起作用。就我所记得的,我们不能直接使用Elem
和List
,所以我有点困惑。我请求帮助,我将感谢您的帮助=)这里有一个解决方案:
%% evenmembers(+List, -ListOfEvenPlacedMembers).
% true when ListOfEvenPlacedMembers is a list of the elements of List at even places.
%
1| evenmembers([],[]).
2| evenmembers([_Odd], []).
3| evenmembers([_Odd,Even|List], [Even|Evens]) :-
4| evenmembers(List, Evens).
下面是这些行的翻译:
write/1
。但是,如果要使用io谓词格式化输出,可以通过添加辅助谓词来实现:
format_evenmembers(List) :-
evenmember(List, Evens),
format("Even members are ~w", [Evens]).
这里有一个解决方案:
%% evenmembers(+List, -ListOfEvenPlacedMembers).
% true when ListOfEvenPlacedMembers is a list of the elements of List at even places.
%
1| evenmembers([],[]).
2| evenmembers([_Odd], []).
3| evenmembers([_Odd,Even|List], [Even|Evens]) :-
4| evenmembers(List, Evens).
下面是这些行的翻译:
write/1
。但是,如果要使用io谓词格式化输出,可以通过添加辅助谓词来实现:
format_evenmembers(List) :-
evenmember(List, Evens),
format("Even members are ~w", [Evens]).
这看起来像是家庭作业,但我将通过展示一个类似的示例为您指出正确的方向
even_members([], []).
even_members([_], []) :- !.
even_members([_,Even|Tail], [Even|Result]) :-
even_members(Tail, Result).
给
?- even_members([1,5,3,2], X).
X = [5, 2].
我们取列表顶部的第二个元素(始终是位置均匀的元素),并将其添加到包含答案的列表中。然后使用尾部递归地遍历列表
基本情况是当我们到达列表的末尾时。由于我们一次遍历列表2个元素,对于偶数长度的列表,我们将得到一个空列表,对于奇数长度的列表,只剩下一个元素(正如aBathologist所指出的)。一旦我们到达一个基本情况,我们将构建一个返回递归树的列表
我的示例将答案存储在一个列表中,这通常是您想要的(列表在Prolog中很常见)。在解决方案中,您不希望将结果存储在列表中
另外,我已经有一年多没有写任何序言了,所以希望我仍然知道我在说什么。这看起来像是家庭作业,但我将通过展示一个类似的例子为您指出正确的方向
even_members([], []).
even_members([_], []) :- !.
even_members([_,Even|Tail], [Even|Result]) :-
even_members(Tail, Result).
给
?- even_members([1,5,3,2], X).
X = [5, 2].
我们取列表顶部的第二个元素(始终是位置均匀的元素),并将其添加到包含答案的列表中。然后使用尾部递归地遍历列表
基本情况是当我们到达列表的末尾时。由于我们一次遍历列表2个元素,对于偶数长度的列表,我们将得到一个空列表,对于奇数长度的列表,只剩下一个元素(正如aBathologist所指出的)。一旦我们到达一个基本情况,我们将构建一个返回递归树的列表
我的示例将答案存储在一个列表中,这通常是您想要的(列表在Prolog中很常见)。在解决方案中,您不希望将结果存储在列表中
另外,我已经有一年多没有写任何序言了,所以希望我仍然知道我在说什么。在序言中,通常先用逻辑自然语言思考问题,然后尝试将其翻译成序言 您需要的是一条规则
evenmember(X,L)
,如果X
是L
的偶数成员,则该规则是正确的。如果我们能够正确定义此规则,那么解决方案将是L
的每个偶数成员。所以用自然语言表达:
1) X is an even member of L if X is the second element of L.
因此,我将在序言中说明:
evenmember(X, [_, X|_]). % The 2nd member of a 2-element list is an even member
这只描述了第一个偶数成员。其余偶数成员可以递归描述:
2) X is an even member of L if X is an even member of the tail of L
ignoring the first two elements.
把这个翻译成Prolog,看看你得到了什么。这个也不需要剪。你必须在削减开支时保持保守。他们的意思是你想要修剪搜索树。在这种情况下,这意味着您可以停止寻找有效的解决方案(找到所有偶数成员)
请注意,我给出的描述假设您希望在每次调用谓词时得到列表中的一个(更具体地说,是下一个)偶数成员,而不是一次得到整个偶数列表,因为原始描述表明了这一点。在Prolog中,首先考虑逻辑自然语言的问题通常会有所帮助,然后试着把它翻译成序言 您需要的是一条规则
evenmember(X,L)
,如果X
是L
的偶数成员,则该规则是正确的。如果我们能够正确定义此规则,那么解决方案将是L
的每个偶数成员。所以用自然l表示