在prolog中扁平化 - 就像其他一样

时间:2016-05-18 16:10:57

标签: prolog

看看我的flatten实现:一般来说,它是有效的。问题仅适用于my_flatten([], F) - 它提供F=[]; F=[[]]而不是F=[]

my_flatten(L, X) :-
   my_flatten(L, X, []). %, reverse(F, X).

my_flatten([], Acc, Acc).
my_flatten([H|T], F, Acc) :-
   my_flatten(H, F1, Acc),
   my_flatten(T, F, F1), !.                         
my_flatten(X, [X|Acc], Acc).        

对于my_flatten(X, [1,2,3])这个程序循环 - 没关系,因为存在无限多的答案,如:[[],[],[],[],1,2,3]
但是,与上面相同的问题 - 对于my_flatten(X, []),它也应该循环,但会给出[]; [[]]

此外,结果是反转 - 但我不关心它 - 如果我取消注释reverse它会没问题 - 但是然后它返回false而不是上面提到的循环。

您是否可以帮助我更改此代码,以便[]返回my_flatten([], X)

我实施了@lurker的建议:

my_flatten(L, F) :-
   my_flatten(L, X, []),
   reverse(F, X).

my_flatten([], Acc, Acc).
my_flatten([H|T], F, Acc) :- 
   is_list(H), 
   my_flatten(H, F1, Acc),
   my_flatten(T, F, F1).
my_flatten([X|T], F, Acc) :-
   not(is_list(X)),
   my_flatten(T, F, [X|Acc]).

1 个答案:

答案 0 :(得分:3)

在回答您的实际问题之前,我对使用flatten/2

有一条评论

<强>不

原因:flatten/2不是真正的关系。例如,我们有:

?- X = [a], flatten(X, Ls).
X = [a],
Ls = [a].

但:

?- flatten(X, Ls), X = [a].
X = [a],
Ls = [[a]].

从逻辑的角度来看,这显然毫无意义。

请使用append/2来精确删除一层的嵌套,并尝试实施

提示:使用

我知道在许多Prolog课程中都会显示或要求flatten/2。这并不意味着它有用,有价值,有启发性或类似的东西。

现在,问你的实际问题:

始终也尝试最常见的查询:

?- my_flatten(X, Ls).
X = Ls, Ls = [] ;
X = [[]],
Ls = [].

从那里开始接受:这个答案是过于笼统过于具体还是两者?想一想。

然后,考虑一下这个论点必须包含哪些内容才有意义,即在什么条件下我们甚至可以给出通过进一步实例化无法呈现的非合理的答案?

它将帮助您阅读Prolog中的