3

使用 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

波纹管是第一个,最后一个,成员的功能

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

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

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

谢谢,

埃里克:)

4

1 回答 1

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 有变量,但它没有 assignables

H1 is H, H1 == T令人难以置信的是,H 既是列表的头部,又相当于尾部。这永远不可能,因为尾部是一个列表,头部是一个元素。即使你可以创造一个真实的情况,这个谓词肯定不会有趣。你这里的递归步骤真的很奇怪。

您的案例分析的另一个问题,案例#3 应该是正确的。With [X],X是列表​​的第一个和最后一个元素,因此fela/1对于所有单元素列表都应该是微不足道的。

我会提倡额外的研究。我认为你有一些奇怪的想法,多读一点可能会纠正。

于 2013-07-19T19:32:27.763 回答