Prolog-在列表中查找相邻元素 [英] Prolog - Finding adjacent elements in a list

查看:80
本文介绍了Prolog-在列表中查找相邻元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图定义一个谓词adjacent(X, Y, Zs),如果X和Y在列表中相邻,则该谓词为true.我的代码当前是这样:

I'm trying to define a predicate adjacent(X, Y, Zs) that is true if X and Y are adjacent in a list. My code is currently this:

adjacent(_, _, []).
adjacent(X, Y, [X, Y|Tail]) :-
  adjacent(X,Y, Tail).

它适用于adjacent(c, d, [a, b, c, d, e])的基本情况,但由于有基本情况,其他所有情况也都返回true,因此我坚持了这一点.

It works for the basic case of adjacent(c, d, [a, b, c, d, e]), but due to the base case, every other case returns true as well, and I'm stuck on that.

另一个问题是,如果X不等于列表头部的第一部分,那么它将跳过X和Y并转到下一个"X";例如,如果 c 不等于 a ,则它会跳过同时通过 a b 并检查是否 c 等于 c .例如,当列表为

The other problem is that if X is not equal to the first part of the list's head, then it skips past both X and Y and goes to the next 'X'; e.g., if c isn't equal to a, then it skips past both a and b and checks if c is equal to c. This is problematic when, for example, the list is

[a, c, d, e]

因为它最终永远不会检查 c (我相信).

because it ends up never checking c (I believe).

我对如何调和这两个问题以及将我对需要发生的事情的逻辑理解变成代码非常迷茫.

I'm pretty lost on how to reconcile the two issues and turn my logical understanding of what needs to occur into code.

感谢Christian Hujer的回答,我的基本情况错误已得到纠正,所以现在我只停留在第二个问题上.

Thanks to Christian Hujer's answer, my base case mistake has been corrected, so now I'm just stuck on the second issue.

推荐答案

在原始解决方案尝试中:

In the original solution attempt:

adjacent(_, _, []).
adjacent(X, Y, [X, Y|Tail]) :-
    adjacent(X,Y, Tail).

正如@ChristianHujer指出的那样,第一个子句不应存在,因为它不是真的.空列表应该没有相邻的元素.

As @ChristianHujer points out, the first clause should not be there because it isn't true. The empty list should have no adjacent elements.

第二个子句也是有问题的.它显示XY在列表中是相邻的,但是随后递归并且不仅成功.适当的子句应为:

The second clause is also problematic. It shows that X and Y are adjacent in the list, but then recurses and doesn't just succeed. A proper clause should be:

adjacent(X, Y, [X,Y|_]).

其中说XY是列表中的前两个元素,无论它们的尾巴是什么,都在列表中相邻.这也构成了适当的基本情况.然后,您的一般递归子句应处理其余情况:

Which says that X and Y are adjacent in the list if they're the first two elements in the list, regardless of what the tail is. This also forms a proper base case. Then your general, recursive clause should take care of the rest of the cases:

adjacent(X, Y, [_|Tail]) :-
    adjacent(X, Y, Tail).

这表示XY如果在Tail中相邻,则在[_|Tail]中相邻.这可以解决您遇到的第二个问题.

This says that X and Y are adjacent in [_|Tail] if they're adjacent in Tail. This takes care of the second problem you were encountering.

因此,整个解决方案将是:

Thus, the whole solution would be:

adjacent(X, Y, [X,Y|_]).
adjacent(X, Y, [_|Tail]) :-
    adjacent(X, Y, Tail).

此操作将成功完成,直到XY以此顺序在列表中一起出现.


使用DCG也可以自然解决此问题(尽管@repeat的基于append/3的解决方案更为简洁):

This will succeed as many times as X and Y appear together, in that order, in the list.


This is also naturally solvable with a DCG (although @repeat's append/3 based solution is more concise):

adjacent(X, Y) --> ..., [X, Y], ... .
... --> [] | [_], ... .

adjacent(X, Y, L) :- phrase(adjacent(X, Y), L).


| ?- adjacent(b, c, [a,b,c,d]).

true ? a

(1 ms) no
| ?- 

这篇关于Prolog-在列表中查找相邻元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆