2013-07-08 30 views
0

我有幾個prolog謂詞來計算給定城市的成本。該過程開始於這樣的命令:best_route([std, lhr, bud, dse], 2013-5-5, X).Prolog回溯並丟失所有值

best_route(Cities, StartDate, Cost):- 
    begin_routing(Cities, StartDate, Cost, []). 

begin_routing(Cities, StartDate, Cost, CostList):- 
    route(Cities, StartDate, CostList), 
    min_list(CostList, Cost). 

route(Cities, StartDate, Costing):- 
    % stop if all cities have been covered once. 
    length(Cities, Stop), 
    length(Costing, Stop); 

    [Origin, Dest|_] = Cities, 
    flights(Origin, Dest, StartDate, Costing, Cities, [Cities, Origin, StartDate]). 

使用在SWI-Prolog的跟蹤功能,我發現,一旦路由謂詞 - length(Costing, Stop)被滿足,即,成本計算表的長度是等於停止。 Prolog代替在那裏停止,並且繼續min_list(CostList, Cost),而是回溯直到CostLost再次丟失所有值。一旦完成後,當列表爲[]時,它將轉到min_list

我不知道爲什麼會發生這種情況。任何幫助表示讚賞。

編輯:

flights(..):- 
    % Code omitted. 
    get_next_date(OriginalDate, NextDate), 
    route(Cities, NextDate, [DayCost|Costing]). 
    % where DayCost is a simple integer calculated before this is added to the current Costing list 

接近年底,最後的正確調用route([std, lhr, bud, dse], 2013-5-6, [329, 499, 323, 311]).

+0

通過閱讀'best_route'和'begin_routing',看起來當第一次調用'route'時,'Cities'被實例化爲'[std,lhr,bud,dse]'並且Costing被實例化爲' ]'。對'length(Costing,Stop)'的調用變爲'length([],4)'並且失敗。它在一個析取(';')中被終止,因此'route'不會在這一點失敗,而是繼續'[Origin,Dest | _] = Cities'實例化'Origin'和'Dest',然後調用' flights'。既然你沒有顯示'航班'的功能,它不知道它從那裏做了什麼。 – lurker

+0

@mbratch:請看看編輯過的問題,我忽略了部分代碼,因爲它們相當不必要和冗長。希望這更清楚。 – Namit

+0

@Namit:min_list(CostList,Cost)失敗或需要更多評估?強制終止,添加一個愚蠢的選擇:(min_list(CostList,Cost); true) – CapelliC

回答

0

看來的CostList的目的是爲了記錄不同路線的成本,然後選擇一個成本最低。但是,初始化CostList[],並且在遞歸建立CostList時,您不提供在遞歸返回時將其傳回的方法。一個可能的解決方案是添加一個新的參數FinalCostList,它正在簡單地通過遞歸直到終止子句。或者,您可以使用差異列表。

爲了說明這一點,請看下面的例子:

p :- q([]). 
q(X) :- go(X), !, q([a|X]). 
q(X) :- stop(X). 

一些相互排斥gostop。計算所需結果(q,所有a s只要go),但不返回。更好的解決方案是

p(Y) :- q([],Y). 
q(X,Y) :- go(X), !, q([a|X],Y). 
q(X,X) :- stop(X). 

如上所述的差異列表也可以使用。

+0

感謝您的答案,但只是要清楚你是否應該將CostList的內容複製到另一個通過遞歸? – Namit

+0

基本上是的。您還可以考慮將傳遞信息合併到遞歸中的差異列表。 –