Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 在序言中展平-类似于其他内容_Prolog_Dcg_Instantiation Error - Fatal编程技术网

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 = [].