2016-05-31 73 views
2

所以我有一个应该很容易解决的问题,来到这个地方,我知道我正在处理的这个程序的流程。如何在递归调用规则时停止回溯

有代码出现,但这段代码我贴在这里被称为本:

pairs_nodes_arcs(C, C, SalidaCreacionEnum, EnumArcos). 

它应该做的:旅行通过第二个参数,直到它是空的,发现如果它符合一切条件,如果它那么,给出已经形成的输出列表(EnumArcos应该保留答案),因为条件是“答案”(我有意通过回溯到代码的其余部分“发送”,因为它是真正问题的答案)。

现在,如果失败,它应该(并且),删除第三个参数的头部,这是一个列表的列表,并“重新启动”第二个参数(我也这样做,因为我一直持有这是第一个参数的副本,与原来的第二个参数相同)。

正如我所说,它应该返回,在它的第四个参数,答案列表。它确实如此,当我使用跟踪时,我在那里看到了正确的答案(最后!!),但它会丢失,因为当它回溯时,该答案列表变空,最终返回空。

我刚才在这里读到http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse9基本查询是强制性的。但我无法弄清楚(从严格意义上说,我的代码并没有陷入无限循环,即使它是愚蠢的运气,也不是问题)。问题是,当回溯时,我放弃了答案。

pairs_nodes_arcs(_, _, [],_). 
pairs_nodes_arcs(_, [], _,_). 
pairs_nodes_arcs([], _, _, _). 
pairs_nodes_arcs([A-B | T],[C-D | Tail0], [H|NODES], LISTARCS) :- 
    member(enum(NODE_ID_C, C), H), 
    member(enum(NODE_ID_D, D), H), 
    REMAINDER is abs(NODE_ID_C-NODE_ID_D), 
    arcs_are_repeated([A-B | T], [C-D | Tail0], [H|NODES], REMAINDER,LISTARCS). 

arcs_are_repeated([A-B | T], [_ | Tail0], [H|NODES], REMAINDER, ListArcsInput):- 
    %maplist(dif(enum(REMAINDER,_)), ListArcsInput), 
    myMapList(enum(REMAINDER,_),ListArcsInput), 
    pairs_nodes_arcs([A-B | T], Tail0, [H|NODES], [enum(REMAINDER, A-B) | ListArcsInput],). 

arcs_are_repeated([A-B | T], [_], [H|NODES],_,_):- 
    pairs_nodes_arcs([A-B | T], [A-B | T], NODES, []). 


myMapList(_, []). 
myMapList(enum(NUM1,_), [enum(NUM2,_)|InputList]):- 
    dif(NUM1,NUM2), 
    myMapList(enum(NUM1,_), InputList). 

我也有痕迹,我只粘贴在那里我觉得我“松回答特定部分(我手动分离的第四个参数给它强调,这是相同的括号内的所有部分):

pairs_nodes_arcs([a-b, b-c], [], [[enum(1, c), enum(3, b), enum(2, a)], [enum(2, c), enum(1, b), enum(3, a)], [enum(2, c), enum(3, b), enum(1, a)], [enum(3, c), enum(1, b), enum(2, a)], [enum(3, c), enum(2, b), enum(1, a)]], 


[enum(2, a-b), enum(1, a-b)]) 


Exit:pairs_nodes_arcs([a-b, b-c], [], [[enum(1, c), enum(3, b), enum(2, a)], [enum(2, c), enum(1, b), enum(3, a)], [enum(2, c), enum(3, b), enum(1, a)], [enum(3, c), enum(1, b), enum(2, a)], [enum(3, c), enum(2, b), enum(1, a)]], [enum(2, a-b), enum(1, a-b)]) 
Exit:arcs_are_repeated([a-b, b-c], [b-c], [[enum(1, c), enum(3, b), enum(2, a)], [enum(2, c), enum(1, b), enum(3, a)], [enum(2, c), enum(3, b), enum(1, a)], [enum(3, c), enum(1, b), enum(2, a)], [enum(3, c), enum(2, b), enum(1, a)]], 2, 


[enum(1, a-b)]) 


Exit:pairs_nodes_arcs([a-b, b-c], [b-c], [[enum(1, c), enum(3, b), enum(2, a)], [enum(2, c), enum(1, b), enum(3, a)], [enum(2, c), enum(3, b), enum(1, a)], [enum(3, c), enum(1, b), enum(2, a)], [enum(3, c), enum(2, b), enum(1, a)]], 


[enum(1, a-b)]) 

EDIT1好了,所以我解决这个的办法,到目前为止似乎是传递一个空列表,这是我工作,我总是不断地为自己的变量。然后,当取得成功的基本情况成功,我将解决方案的操作列表与变量统一起来,我至少在代码中做了3次,并且需要1次更多的时间。尽管100%是一种​​很好的方式,但我最终得出了一些论点,但是......我的意思是这种方法似乎存在问题,但至少它是一个问题。

+0

关于** edit1 **:这绝对是一种方式。更好的方法是简单*进一步实例化部分列表,以便在谓词成功时由所有元素组成。例如,你从'Ls0'开始,谓词说:'Ls0 = [First | Rest]',然后是关于Rest的原因。一种非常好的方式来有效地描述列表:[tag:dcg]。 – mat

+0

这就是我想要做的,当它成功地抓住每一个元素。但是我一定是做错了什么,因为它没有正确地绑定,不管什么(我认为其他更简单的代码片段,我认为这是一个编码不佳的问题,我猜)。我可能会试着再读一遍关于DCG的文章,但是每次我尝试之前,我都很少理解。也许现在我有更多的经验... – keont

+1

你的一个子句可能是*太普通*。我会用“进一步实例化”的方法或用DCG描述列表。 – mat

回答

3

你的答案是回溯(回溯发生在失败),但对成功:您希望您的程序成功具有特异结合,但它 

要调试这一点,认为声明:写下应该成功一个目标,但失败

在你的榜样,查询:

 
?- arcs_are_repeated([a-b, b-c], [b-c], [[enum(1, c), enum(3, b), enum(2,a)], 
    [enum(2, c), enum(1, b), enum(3, a)], [enum(2, c), enum(3, b), enum(1, a)], 
    [enum(3, c), enum(1, b), enum(2, a)], [enum(3, c), enum(2, b), enum(1, a)]], 
    2, [enum(1, a-b)]). 

可以是这样的一个例子。

然后,使目标更一般,以这样一种方式,它仍然失败。例如,下列情况是否仍然失败:

 
?- arcs_are_repeated([a-b, b-c], [b-c], [[enum(1, c), enum(3, b), enum(2,a)], 
    [enum(2, c), enum(1, b), enum(3, a)], [enum(2, c), enum(3, b), enum(1, a)], _], 2, _). 

如果是,则进一步推广。比如,怎么样:

 
?- arcs_are_repeated([a-b, b-c], _, _, _, _). 

如果失败,你缩小了你还没有考虑到的情况下,无论哪个参数。

这是你如何调试声明:想想应该成功,但是失败了,想想什么应该失败,但成功。在前一种情况下,您的程序也是也 特定,而在后者中,它也是 一般。你的情况,实在是太特殊,所以你要么需要:

  • 添加从句或
  • 删除现有条款一个约束

使程序更一般。

+0

目前检查你的答案,以了解它(顺便说一句,仍然处理前一部分,与代码,这很难,但我觉得整体上改善)。我只想说谢谢,有时我不知道如何回答自己为什么要上大学。你成功了,因为我的老师由于缺乏兴趣(正确解释概念)而失败了。所以谢谢。 – keont

+1

我正在使用的方法取决于几年前才广泛且免费提供的技术。例如,CLP(FD)限制可用于更少(更昂贵)的系统。 “dif/2”没有那么广泛。这需要几年甚至几十年的时间,直到现在可以传播到教科书和教师教育中,并从那里传播到下一代Prolog程序员。例如,如果你仍然使用低级算术谓词或非单调结构(如'!/ 0'),那么上面概述的内容不能完成。 – mat

+0

真是太不可思议了。对于像我一样一直在研究互联网的人(至少是单身),因为某些知识大部分都不可用......另一方面,我现在意识到我需要小心。解决方案必须运行在某个程序中(ciao ...),我只会在我尝试它时发现它(当前在线编程,这是该程序的坏处)。 – keont