我只接触 Prolog 几天时间。虽然有些东西我已经理解了,但这个问题真的让我感到困惑。
我需要编写一个函数,接收一个列表并将其展平。
?- flatten([a,[b,c],[[d],[],[e]]],Xs).
Xs = [a,b,c,d,e]. % expected result
这个函数将提取列表的内部结构。
目前我已经有了以下代码:
flatten2([],[]).
flatten2([Atom|ListTail],[Atom|RetList]) :-
atom(Atom), flatten2(ListTail,RetList).
flatten2([List|ListTail],RetList) :-
flatten2(List,RetList).
现在,当我调用以下代码时,它可以正常工作:
?- flatten2([a,[b,c],[[d],[],[e]]], R).
R = [a,b,c,d,e]. % works as expected!
但是当我调用查看输入的列表是否已经被展平时,它返回false
而不是true
:
?- flatten2([a,[b,c],[[d],[],[e]]], [a,b,c,d,e]).
false. % BAD result!
为什么在一只手上可以工作,而在另一只手上却不能?我感觉自己忽略了某些非常简单的东西。
?- flatten([X], Ls).
应该产生什么结果?你可能认为它“显然”应该产生Ls = [X]
。然而,你会遇到以下问题:?- flatten([X], Ls), Ls = [X], X = [a].
成功,但是如果我们通过连词的交换性来简单地交换目标,我们得到:?- Ls = [X], X = [a], flatten([X], Ls).
,或者更简洁地说,?- flatten([[a]], [[a]]).
,这当然必须失败,因为[[a]]
不是一个平坦的列表。那么,它是成功还是失败呢?这表明这真的不是一个好的关系。 - matappend/2
。它将此关系限制为更有意义且通常也更实用的版本。 - mat