使用Prolog:给定列表检查列表的第一个元素是否等于最后一个元素

时间:2013-07-19 19:22:21

标签: list recursion prolog

使用prolog,我必须创建一个规则,在给定列表时,确定列表的第一个元素是否等于列表的最后一个元素。以下是我的想法。

The Base Cases:
1) If The Parameter Is Not A List: Return False
2) If The Parameter Is A List But Empty: Return False 
3) If The Parameter Is A List But Has One Element: Return False

The Recursive Step:
Recursively Going Through The List Getting The 
First Element And TheLast Element Then Compare

fela() :- false.                             <-- Base Case One
fela([]):-false.                             <-- Base Case Two
fela([H]):-false.                            <-- Base Case Three
fela([H|T]):- H1 is H, H1 == T, fela(T,H1).  <-- Recursive Step

Bellow是第一个,最后一个,会员的功能

first(F, [F|_]).
last(L, [H|T]) :- last(L, T).

member(X, [X|_]).
member(X, [_|T]) :- member(X, T).

我在递归步骤时遇到问题,我不确定如何存储第一个元素,并遍历列表并获取最后一个元素,然后比较结果的真/假答案。有人可以帮帮我

谢谢,

Erik:)

1 个答案:

答案 0 :(得分:5)

这是一个简单的问题:

fela(L) :- first(E, L), last(E, L).

盯着它看一分钟让它真的沉入其中。

实际上,它是正确的,但是你的last/2不是,只是遍历列表而没有基本情况会成功。正确的last/2看起来像这样:

last(L, [L]).
last(E, [_|L]) :- last(E, L).

我在你的案例分析中看到了很多困惑的想法。首先,在Prolog中,您没有明确地返回true和false。你只需匹配你匹配的东西,剩下的就是失败。处理列表时,您会自动继承空列表的基本情况以及元素的归纳情况和列表的其余部分。这不足以从头开始实现fela/1因为你无法记住你的第一个元素是什么。因此,如果你想从头开始构建它,你需要一个帮助器谓词,这样你就可以继续传递第一个元素。它看起来像这样:

fela([H|T]) :- fela(H, T).

fela(First, [First]).
fela(First, [_|Xs]) :- fela(First, Xs).

请注意,我们保留了对一个基本案例的分析,一个用于处理列表的归纳案例。这是处理递归数据结构时的常见情况。 first/2是您不遵守规则的一个很好的例子,因为您对其中一个案例不感兴趣。从first/2last/2构建谓词可以让你完全逃避案例分析问题,而且(在我看来)更常见的是在实践中发生的事情。

现在我想在这里列出你的一些想法以获得进一步的评论。首先,H1 is H绝对不是你想要的。 is/2专门用于减少算术表达式。您将始终在左侧有一个变量,在右侧有一个表达式,或者它没有意义。你在这里尝试做某种任务,但即使H1 = H在这里也没有用,因为虽然Prolog有变量,it does not have assignables

H1 is H, H1 == T令人难以置信地说,H既是列表的头部,又等同于尾部。这实际上是不可能的,因为尾部是一个列表而头部是一个元素。即使你可以设计出真实的情况,这个谓词也绝对不会有趣。你在这里的递归步骤真的很奇怪。

案例分析的另一个问题,案例#3应该是真的。使用[X]时,X既是列表的第一个也是最后一个元素,因此对于所有单元素列表,fela/1应该是真的。

我会提倡进一步研究。我认为你有一些奇怪的想法,更多的阅读可能会纠正。