将最后一个元素一分为二,给出最后一个元素和一个休息列表

时间:2018-09-28 10:49:34

标签: list prolog

例如,给定列表[1,2,3,4,5],我想找到最后一个元素(5)和其余的“休息列表”,即[1,2,3,4]。

我考虑过反转列表,拆分第一个元素,然后再反转拆分列表。但是无法弄清楚如何为此编写谓词。如果有更好或更简单的解决方案是理想的选择,那么我还没有通过Google搜索找到任何东西。

1 个答案:

答案 0 :(得分:1)

在Prolog中,一个目标(通常带有归纳定义)旨在描述谓词中的参数如何彼此“关联”,而不是如何将输入“转换”为输出。这意味着许多谓词,例如member/3append/3可以以多向的方式使用。

  

示例1 :我们可以在归纳定义中将append/3 [swi-doc]定义为:

     
      
  1. 如果X是一个空列表,则对于append(X, Y, Z)YZ相同;和
  2.   
  3. 如果X是非空的,则我们为列表append/3(不含第一个元素和X)计算Y,并将列表{{1 }},第一个元素为ZT
  4.   
     

然后我们可以将其翻译为:

X

  

示例2 :以类似的方式,我们可以定义“过滤器”。例如,我们可能想要获取列表中大于3的所有元素。我们可以归纳地定义为:

     
      
  1. 一个空列表中大于三个的元素就是空列表;
  2.   
  3. 在第一个元素小于或等于3的非空列表中大于3的元素是大于该列表其余项目中3个的元素的列表;和
  4.   
  5. 非空列表中大于三个的元素(其中第一个元素大于三个)是大于列表其余三个元素的元素列表,并以列表的第一个元素为前缀。
  6.   
     

然后我们可以将其翻译为:

append([], Y, Y).               %% (1)
append([XH|XT], Y, [XH|ZT]) :-  %% (2)
    append(XT, Y, ZT).

以上示例对于列表处理而言是非常典型的,通常有一个(或几个)基本案例处理一个空列表,或者一个具有固定数量元素的列表,然后有一个(或几个) )处理非空列表的递归案例,这些案例是用归纳法(根据谓词)编写的。

在这里,您的基本情况将处理空列表,因为对于空列表,没有“ last”元素。基本情况将处理带有 one 元素的列表。

因此,递归情况将处理包含至少两个元素的列表,因此应根据谓词本身进行定义。

因此,我们可以将归纳定义写为:

  1. 具有一个元素的列表的“ init”和“ last”是...。
  2. 具有至少两个元素的列表的“ init”和“ last”可以定义为...的init和last,以及we ...

因此,“骨架”如下所示:

larger_three([], []).          %% (1)
larger_three([H|T], F) :-      %% (2)
    H =< 3,
    larger_three(T, F).
larger_three([H|T], [H|F]) :-  %% (3)
    H > 3,
    larger_three(T, F).

带有需要填写的initlast([X], ___, ___). initlast([X1, X2|T], __, ___) :- ___, initlast(___, ___, ___), ___. 元素。正文中的___定义了预处理后处理,并且可能根本不存在。