2017-12-18 305 views
3

我剛剛在序言開始了,我希望能執行以下任務:在Prolog中是否有相當於Haskell的enumFromTo?

做謂語A(P,N,L)使得對所有C這是LP(N,C)第n個元素。

基本上我想執行範圍[0..N]的地圖。 在Haskell,我最熟悉的語言,這看起來像

f p n = map(p)[0..n] 

(哈斯克爾不相當有謂語,所以我在這裏採取了一些自由)

或pointfree

f = (.enumFromTo 0).map 

而且看起來我應該能夠在Prolog中輕鬆完成它。 Prolog的maplist/3基本上已經是這樣了,所以它應該是一個微不足道的修改。我的定義應該看起來像這樣:

A(P,N,L) :- maplist(P, ??? , L). 

但是我真的不知道要把什麼放在空白處。在Haskell中,我將使用像enumFromTo這樣的函數,但似乎Prolog中不存在這樣的事情。關閉當量將是between/3,但這不是一個清單,所以我不能使用maplist

或者我可以做我自己的範圍謂詞。

我想的第一件事是:

range(0,[0]). 
range(N,[N|T]) :- range(N-1,T). 
A(P,N,L) :- range(N,rangeN), maplist(P, rangeN, L). 

但我不能得到這在所有的解決。我也試過

range(N,L):-findall(X,between(0,N,X),L),sort(L,L). 
A(P,N,L) :- range(N,rangeN), maplist(P, rangeN, L). 

但是,對於這樣一個小問題,看起來真的很笨拙。

我該如何填補我的maplist中的空白?我以錯誤的方式接近問題嗎?

+1

我認爲錯誤的方法。 Haskell是懶惰的,因此整個列表不會一次存在,所以映射到列表上就好了。在Prolog中,你應該做一個遞歸謂詞,只更新一個整數。 –

回答

2
-- % f p n = map (p) [0..n] = [p 0, p 1, p 2, ..., p n] 

被翻譯成的Prolog作爲

f(P,N,L):- f(P,0,N,L). 
f(P,I,N,[]):- I > N. 
f(P,I,N,L):- call(P,I,X), 
      (N =:= I -> L = [X] 
      ; L = [X|T], J is I+1, f(P,J,N,T)). 

這假定p :: Int -> a一些a,由Haskell代碼所暗示。

這也假定給出了具體的(「地面」)可調用雙參數謂詞P和整數N

另一種可能性是

g(P,N,L):- findall(X, (between(0, N, I), call(P,I,X)), L). 

此查找所有X S,從而使0 <= I <= NP(I,X)成立。

測試在SWI-Prolog的:

11 ?- [user]. 
add1(X,Y):- Y is X+1. 
|: 

12 ?- f(add1,5,L). 
L = [1, 2, 3, 4, 5, 6]. 

13 ?- g(add1,5,L). 
L = [1, 2, 3, 4, 5, 6]. 
2

當我的溶液試圖代碼中的Prolog到N後問題,如從Picat家表示(參見實施例5,靠近頁的結束),我遇到了類似的問題。這是我的最終結果,並評論了一些替代方案:

:- use_module(library(clpfd)). 

queens(N, Q) :- 
    length(Q, N), 
    Q ins 1..N, 
    all_different(Q), 
    maplist_index([I,V,P]>>(P#=V+I),1,Q,Ps),all_different(Ps), 
    maplist_index([I,V,M]>>(M#=V-I),1,Q,Ms),all_different(Ms), 
    /* no 
    bagof(P, (nth1(I,Q,V), P #= V + I), Ps), all_different(Ps), 
    bagof(M, (nth1(I,Q,V), M #= V - I), Ms), all_different(Ms), 
    */ 
    /* ok 
    all_different_p(Q, 1, P), all_different(P), 
    all_different_m(Q, 1, M), all_different(M), 
    */ 
    label(Q). 

all_different_p([Q|Qs], I, [P|Ps]) :- 
    P #= Q + I, 
    succ(I, J), 
    all_different_p(Qs, J, Ps). 
all_different_p([], _I, []). 

all_different_m([Q|Qs], I, [P|Ps]) :- 
    P #= Q - I, 
    succ(I, J), 
    all_different_m(Qs, J, Ps). 
all_different_m([], _I, []). 

maplist_index(P, I, [X|Xs], [Y|Ys]) :- 
    call(P, I, X, Y), 
    succ(I, J), 
    maplist_index(P, J, Xs, Ys). 
maplist_index(_, _, [], []). 

maplist_index/4是一個你需要的例子。值得注意的是bagof/3在屬性變量存在的情況下效果不佳。

相關問題