2016-12-13 60 views
1

所以,我堅持這個問題幾個小時,我似乎無法找到解決方案。
我需要給定當前日期,並且知道飛機在星期二,星期四和星期六的6:00起飛,計算下一次起飛的日期和時間。 我把這個信息在事實的形式(第二個參數表示星期幾,其中1 =星期一):Prolog:查找下一個日期

departure(time(6,0,0), 2). 
departure(time(6,0,0), 4). 
departure(time(6,0,0), 6). 

有人能幫助我嗎? 謝謝。

回答

0

我提出以下解決方案,我會盡力esplain它

selNextDepH([], _, First, First). 

selNextDepH([Hd | _], Now, _, Hd) :- 
    Now @<= Hd. 

selNextDepH([Hd | Td], Now, First, NextDep) :- 
    Now @> Hd, 
    selNextDepH(Td, Now, First, NextDep). 

selNextDep([Hd | Td], Now, NextDep) :- 
    selNextDepH([Hd | Td], Now, Hd, NextDep). 

switchDep(dep(Day, Time), departure(Time, Day)). 

nextDep(DayNow, TimeNow, NextDeparture) :- 
    findall(dep(Day, Time), departure(Time, Day), List), 
    sort(List, ListS), 
    selNextDep(ListS, dep(DayNow, TimeNow), NextDep), 
    switchDep(NextDep, NextDeparture). 

所有在nextDep/3地方開始findall/3收集所有departure/2但收集他們作爲dep/2,按相反的順序(dep(Day, Time)代替departure(Time, Day)),因爲它更容易訂購

findall(dep(Day, Time), departure(Time, Day), List), 

接下來我們名單dep/2List結構與排序

sort(List, ListS), 

所以ListS(列表排序)我們有偏離(在dep/2形式)與天爲第一個關鍵的時間爲第二有序。

接下來,我們稱之爲selNextDep/3尋找下一個出發的dep/2形式(NextDep

selNextDep(ListS, dep(DayNow, TimeNow), NextDep), 

,並與switchDep/2,我們獲得下一個出發的departure/2形式

switchDep(NextDep, NextDeparture). 

swithcDep/2是微不足道的,但selNextDep/3不是(恕我直言)。

selNextDep/3背後的想法是返回(在第三個參數中)排序列表(第一個參數)的第一個sel/2元素,它大於第二個參數(現在的時間)。如果找不到更大的元素,則該想法返回列表的第一個元素(下週第一次離開)。

因此,我刪除了一個簡單的selNextDep/3,它只調用帶有相同參數的幫助子句(selNextDepH/4),並添加了列表的第一個元素(如果找不到更大的元素);即

selNextDep([Hd | Td], Now, NextDep) :- 
    selNextDepH([Hd | Td], Now, Hd, NextDep). 

對於selNextDepH/4終端子句是簡單的:如果該列表爲空,返回(統一與最後一個參數)的列表

selNextDepH([], _, First, First). 

的第一個元素。如果該列表不空的,我們有兩種情況:(1)現在時間比列表的第一個元素低於(或等於),所以我們返回(統一的最後一個參數)的列表

selNextDepH([Hd | _], Now, _, Hd) :- 
    Now @<= Hd. 

的第一要素或(2)現在的時間大於列表的第一個參數,所以我們在下一個列表中尋找更大的出發點

selNextDepH([Hd | Td], Now, First, NextDep) :- 
    Now @> Hd, 
    selNextDepH(Td, Now, First, NextDep).