例如,给定列表[1,2,3,4,5],我想找到最后一个元素(5)和其余的“休息列表”,即[1,2,3,4]。
我考虑过反转列表,拆分第一个元素,然后再反转拆分列表。但是无法弄清楚如何为此编写谓词。如果有更好或更简单的解决方案是理想的选择,那么我还没有通过Google搜索找到任何东西。
答案 0 :(得分:1)
在Prolog中,一个目标(通常带有归纳定义)旨在描述谓词中的参数如何彼此“关联”,而不是如何将输入“转换”为输出。这意味着许多谓词,例如member/3
和append/3
可以以多向的方式使用。
示例1 :我们可以在归纳定义中将
append/3
[swi-doc]定义为:
- 如果
X
是一个空列表,则对于append(X, Y, Z)
,Y
与Z
相同;和- 如果
X
是非空的,则我们为列表append/3
(不含第一个元素和X
)计算Y
,并将列表{{1 }},第一个元素为ZT
。然后我们可以将其翻译为:
X
示例2 :以类似的方式,我们可以定义“过滤器”。例如,我们可能想要获取列表中大于3的所有元素。我们可以归纳地定义为:
- 一个空列表中大于三个的元素就是空列表;
- 在第一个元素小于或等于3的非空列表中大于3的元素是大于该列表其余项目中3个的元素的列表;和
- 非空列表中大于三个的元素(其中第一个元素大于三个)是大于列表其余三个元素的元素列表,并以列表的第一个元素为前缀。
然后我们可以将其翻译为:
append([], Y, Y). %% (1) append([XH|XT], Y, [XH|ZT]) :- %% (2) append(XT, Y, ZT).
以上示例对于列表处理而言是非常典型的,通常有一个(或几个)基本案例处理一个空列表,或者一个具有固定数量元素的列表,然后有一个(或几个) )处理非空列表的递归案例,这些案例是用归纳法(根据谓词)编写的。
在这里,您的基本情况将不处理空列表,因为对于空列表,没有“ last”元素。基本情况将处理带有 one 元素的列表。
因此,递归情况将处理包含至少两个元素的列表,因此应根据谓词本身进行定义。
因此,我们可以将归纳定义写为:
因此,“骨架”如下所示:
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(___, ___, ___),
___.
元素。正文中的___
定义了预处理和后处理,并且可能根本不存在。