List 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]) :- !

我正在用Prolog研究逻辑编程的这个新概念。我曾经处理过切割、失败,现在我的话题是列表。我有以下任务要做: -编写一个函数
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).
下面是这些行的翻译:

  • 空列表的偶数成员是空列表(没有)
  • 包含一个元素的列表的偶数成员是空列表(同样,没有)
  • 包含前两个元素(奇数和偶数)的列表的偶数成员以及剩余列表是其第一个成员为[偶数]且其后续成员为偶数的列表,如果
  • 名单上的偶数成员是偶数
  • 第4行的规则选取列表中的前两个元素,并将第二个(均匀放置的)元素放入均匀放置的元素列表中。如果您在swi prolog解释器中运行此程序,它将为您提供解决方案,而无需使用
    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).
    
    下面是这些行的翻译:

  • 空列表的偶数成员是空列表(没有)
  • 包含一个元素的列表的偶数成员是空列表(同样,没有)
  • 包含前两个元素(奇数和偶数)的列表的偶数成员以及剩余列表是其第一个成员为[偶数]且其后续成员为偶数的列表,如果
  • 名单上的偶数成员是偶数
  • 第4行的规则选取列表中的前两个元素,并将第二个(均匀放置的)元素放入均匀放置的元素列表中。如果您在swi prolog解释器中运行此程序,它将为您提供解决方案,而无需使用
    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表示