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

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

以下是第一个、最后一个和成员函数。
(Note: "Bellow" 应为 "Below")
first(F, [F|_]).
last(L, [H|T]) :- last(L, T).

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

我在递归步骤中遇到了困难,不确定如何存储第一个元素并遍历列表获取最后一个元素,然后比较结果以获得真/假答案。能否有人帮帮我呢?

谢谢,

Erik :)


1
在SO上,你应该接受那个对你最有帮助的答案。 :) - Will Ness
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具有变量,但它没有可分配项H1 is H, H1 == T表示H既是列表的头部又等同于尾部,这是不可信的。这实际上永远不可能发生,因为尾部是列表而头部是元素。即使您可以制造这样的情况,它对该谓词也肯定无趣。这里的递归步骤真的很奇怪。
另一个问题是您的案例分析,第3种情况应该是真实的。对于[X]X既是列表的第一个元素也是最后一个元素,因此fela/1对于所有单个元素的列表都应该是微不足道的真。
我建议进行额外的学习。我认为您有一些奇怪的概念可能需要更多的阅读才能纠正。

1
非常感谢您的帮助,我对Prolog有些不太熟悉,这是我第一次使用这种语言。您为我解答了很多问题。再次感谢您的帮助。 - Erik-Smies
1
@ErikSmiley 不客气。可以点赞/采纳吗? :) 我认为你会没问题的,只要坚持下去。 - Daniel Lyons
OP现在还不能给你点赞,Daniel。:)(他们需要15个声望才能这样做)。感谢提供Robert Harper博客的链接。 - Will Ness
@WillNess 很久没记得限制条件被解除的顺序了。 - Daniel Lyons

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接