2016-05-31 75 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