簡體   English   中英

在Prolog中是否有相當於Haskell的enumFromTo?

[英]Is there an equivalent of Haskell's enumFromTo in Prolog?

我剛剛開始使用Prolog,我希望執行以下任務:

使謂詞A(P,N,L)成為對於作為L第n個元素的所有CP(N,C)

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

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

(Haskell沒有謂詞,所以我在這里采取一些自由)

或者在無點上

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 我是以錯誤的方式解決問題了嗎?

-- % 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 <= N P(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]. 

當我試圖在Prolog中編寫N皇后問題的解決方案時,如Picat home所述(參見示例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在存在屬性變量時效果不佳。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM