在 Prolog 中展平列表 [英] Flatten a list in Prolog

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

问题描述

我只使用 Prolog 几天.我明白一些事情,但这真的让我很困惑.

I've only been working with Prolog for a couple days. I understand some things but this is really confusing me.

我想编写一个函数,该函数接受一个列表并将其展平.

I'm suppose to write a function that takes a list and flattens it.

?- flatten([a,[b,c],[[d],[],[e]]],Xs).  
Xs = [a,b,c,d,e].                           % expected result

该函数取出列表的内部结构.

The function takes out the inner structures of the list.

这是我目前所拥有的:

flatten2([],[]).
flatten2([Atom|ListTail],[Atom|RetList]) :-
      atom(Atom), flatten2(ListTail,RetList).
flatten2([List|ListTail],RetList) :-
      flatten2(List,RetList).

现在,这在我打电话时有效:

Now, this works when I call:

?- flatten2([a,[b,c],[[d],[],[e]]], R).
R = [a,b,c,d,e].                         % works as expected!

但是当我打电话查看我输入的列表是否已经变平时,返回 false 而不是 true:

But when I call to see if a list that I input is already flattened, is returns false instead of true:

?- flatten2([a,[b,c],[[d],[],[e]]], [a,b,c,d,e]).
false.                                   % BAD result!

为什么一方面可以,另一方面不行?我觉得我错过了一些非常简单的东西.

Why does it work on one hand, but not the other? I feel like I'm missing something very simple.

推荐答案

你给出的 flatten2/2 的定义被破坏了;它实际上是这样的:

The definition of flatten2/2 you've given is busted; it actually behaves like this:

?- flatten2([a, [b,c], [[d],[],[e]]], R).
R = [a, b, c] ;
false. 

因此,考虑到您已经将 R 绑定到 [a,b,c,d,e] 的情况,失败也就不足为奇了.

So, given the case where you've already bound R to [a,b,c,d,e], the failure isn't surprising.

您的定义是在第三个子句中丢弃列表的尾部 (ListTail) - 这需要整理并连接回列表以通过 RetList 返回.这是一个建议:

Your definition is throwing away the tail of lists (ListTail) in the 3rd clause - this needs to be tidied up and connected back into the list to return via RetList. Here is a suggestion:

flatten2([], []) :- !.
flatten2([L|Ls], FlatL) :-
    !,
    flatten2(L, NewL),
    flatten2(Ls, NewLs),
    append(NewL, NewLs, FlatL).
flatten2(L, [L]).

这个递归地将所有列表列表缩减为单个项目列表[x],或者它丢弃的空列表[].然后,它将它们全部累加并再次附加到一个列表中输出.

This one recursively reduces all lists of lists into either single item lists [x], or empty lists [] which it throws away. Then, it accumulates and appends them all into one list again out the output.

请注意,在大多数 Prolog 实现中,空列表 [] 是一个原子 一个列表,因此调用 atom([])is_list([]) 都评估为真;这不会帮助你扔掉空列表而不是字符原子.

Note that, in most Prolog implementations, the empty list [] is an atom and a list, so the call to atom([]) and is_list([]) both evaluate to true; this won't help you throw away empty lists as opposed to character atoms.

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

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