Prolog 在序言中展平-类似于其他内容
看看我的扁平化实现:一般来说,它是有效的。唯一的问题是Prolog 在序言中展平-类似于其他内容,prolog,dcg,instantiation-error,Prolog,Dcg,Instantiation Error,看看我的扁平化实现:一般来说,它是有效的。唯一的问题是myu展平([],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), !.
myu展平([],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,[])
它也应该是循环的,但是给出了[];[]]
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).
此外,结果是反向-但我不在乎它-如果我取消注释reverse
,它将是好的-但然后它返回false
,而不是上面提到的循环
您能否帮助我更改此代码,使其返回[]
用于我的展平([],X)
我实施了@潜伏者的建议:
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]).
在回答您的实际问题之前,我对使用
展平/2
有一点看法:
不要
原因:flatten/2
不是真正的关系。例如,我们有:
?- X = [a], flatten(X, Ls).
X = [a],
Ls = [a].
从这里开始:这个答案是否太笼统、太具体,或者两者兼而有之?想想这个
然后,想一想,为了让这个论点有意义,我们必须持有什么样的观点,也就是说,在什么条件下,我们甚至可以给出合理的答案,而这些答案不能通过进一步的实例化而变得非理性
它将帮助您阅读序言中的内容。您似乎对cut运算符有着亲和力(
!
);)让第一个参数有时是一个列表,有时不是,对我来说有一种奇怪的代码味道my|u flatten(X,[X | Acc],Acc)
在这两个位置出现的Acc
看起来有问题。my_flatten/3的逻辑含义尚不清楚。请注意,如果H
是一个列表,那么是列表(H)
是真的,所以如果你觉得它方便的话,你可以使用它。好的,我是切割操作符的兄弟,但是你是切割操作符的敌人:谢谢你的提示。我在第一篇文章中添加了新的解决方案。你怎么看?伤口有它的位置,但用它来“修复”问题是不好的。许多初学者将其用于各种目的,通常是在过程中修补问题,但最终破坏了谓词的适当通用性。我也是cut的朋友,但只有在目的恰当的情况下才是。:)is_list/1
是一个选择非常错误的谓词。对于L=[],is_list(L)
它成功,对于is_list(L),L=[]它失败。谢谢您的回答。你看到新的解决方案了吗?我编辑了我的第一篇文章(使用@Lougler的建议)并创建了工作解决方案。你怎么看?还是没有雪茄:?-my_flatten([[X]],Ls),X=[a]。
成功地使用了Ls=[[a]]
,但没有展平。在无法保证可靠结果的情况下,应该抛出一个。正如我所说的,如果参数还没有充分实例化,则需要抛出实例化错误。对于此类测试,您需要额外的逻辑谓词,如var/1
和ground/1
。查看SWI Prolog中的库(错误)
,了解更多灵感。另外,我强烈建议您干脆忘记flatte/2
:它本质上不是单调的,如果您需要这个谓词,那么您就错设计了数据结构。到目前为止,我所看到的flant/2
的所有用法都应该通过简单地使用append/2
来处理。@mat:为什么functor/3是额外的逻辑函数?它确实忠实地模拟了一个关系(并在困难的情况下产生错误)。好吧,至少我们不能用(有限的)一阶程序实现functor/3
。否则,是的,这是一种关系。
?- my_flatten(X, Ls).
X = Ls, Ls = [] ;
X = [[]],
Ls = [].