2015-03-25 27 views
1

我正在研究Prolog中的約束編程問題,我在嘗試爲列表列表定義一個域時遇到了問題。問題的最初的挑戰如下:Prolog CLPFD試圖爲列表的列表定義域

trains([[1,2,0,1], %from station, to station, departs at, arrives at 
      [2,3,4,5], 
      [2,3,0,1], 
      [3,4,5,6], 
      [3,4,2,3], 
      [3,4,8,9]]). 

    threepath(A,D,Ps):- 
     Ps = [[A,B, _T0, T1], [B,C, T2, T3], [C,D, T4, _T5]], 
     T2 #> T1, 
     T4 #> T3, 
     trains(Ts), 
     tuples_in(Ps, Ts). 

在那之後,我預計將擴大在這個以適應任何數量的列車,而不是隻3.這是我在嘗試這樣做:

anypath(A,D,Ps,N):- 
     length(Ps,N), 
     Ps ins Xs, 
     Xs = [A,B,C,D], 
     Xs ins 1..9. %How to define the domain for a list of length 4 inside a list of variable length. 

但是,我不太清楚如何定義列表的列表域。到目前爲止,我已經定義了長度(Ps,N),以便Ps可以有任何長度。然後,我試圖在Ps中定義變量,以便它們將是長度爲4的列表,但是可怕地失敗了。

此外,我也不確定如何定義可變長度的Ps的約束,例如T2#> T1和T3#> T4的情況3。我所看到的模式是下一個列表的最後一個元素應該比列表中的第三個元素大,但是我仍然停留在表示此約束的語法上。

現在,我試圖用遞歸來設置Ps的頭部長度爲4的列表,並且通過對尾部進行相同的操作,因爲我無法知道列表的長度PS會。

如果有人能夠對此有所瞭解,我將不勝感激。上進展25/3/2015

更新我讀一個MAPLIST用來產生內列出的另一個問題的一個例子。代碼的摘錄是:

length_(Length, List) :- length(List, Length). 

child_row(X) :- X ins 1..16 . 

ww(X) :- 
     write(X), 
     write('/'). 

print_row(Row) :- 
     maplist(ww, Row), 
     nl. 

children(Class) :- 
     length(Class, 4), 
     maplist(length_(4), Class), 
     maplist(child_row , Class), 

從我明白,MAPLIST(length_(4),A類)施加length_(4)內部類的每個元素,並創建長度爲4作爲結果的內部列表。所以,我想這適用於我的問題,這裏是我的嘗試:

length_(Length, List) :- length(List, Length). 
anypath(A,D,Ps,N):- 
    length(Ps,N), 
    maplist(length_(4), Ps), 
    %constraint(Ps), 
    trains(Ts), 
    tuples_in(Ps, Ts). 

不過,我得到一個錯誤信息說「長/ 2:類型錯誤:list' expected, found 4' 」不論N是否被設置爲3或4,我也不太理解這個,因爲它應該和上面的例子一樣,gtrace有點麻煩,以檢測我的錯誤。

我目前卡住了,我會更新,如果我想出任何東西。

所以,我還有一個問題,我希望可以回答的是:「創建內部列表的正常做法是什麼,以及您通常如何自己做?」。

謝謝!

+0

你不能這樣做了'詩插件Xs'當'Xs'不會被實例化的領域。你可以嘗試'Xs = [A,B,C,D],Xs ins 1..9,標籤(Xs),Psins Xs'。 – lurker 2015-03-25 13:33:29

+0

我試過了,但它給了我'域錯誤:'clpfd-domain'顯示,發現'[1,1,1,1]''。自從我從一個站到另一個站並且'T0> T1'時,我做了額外的限制'B#> A',因爲時間會流逝,而且當我旅行時它會增加。這裏是我的更新代碼和你的建議:'anypath(A,D,Ps,N): - \t length(Ps,N), \t Xs = [A,B,T0,T1], \t Xs ins 1。 0.9, \t標籤(XS), \t詩插件XS, \t B#> A, \t T1#> T0, \t列車(TS), \t tuples_in(PS,TS).' – t22000 2015-03-25 17:12:16

+0

爾加抱歉,我對'Ps ins Xs'的建議是愚蠢的...... – lurker 2015-03-25 17:35:43

回答

3

您可以

append(Trains, FlatTrains) 

拼合列表,然後限制FlatTrains

FlatTrains ins 1..9 
+1

s(X)! 'append/2'是刪除恰好一層嵌套的好方法。 – mat 2015-11-12 12:12:07