2017-12-18 15 views
3

は、私はちょうどPrologで出始めてきたと私は、次のタスクを実行するために期待していた。 PrologにHaskellのenumFromToと同等のものがありますか?

は、述語が A(P,N,L)ように作ること LP(N,C)のn番目の要素であるすべての Cため。

基本的には、[0..N]の範囲のマップを実行したいと思います。ハスケル、私が最も精通していた言語で 、これは

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

(Haskellはかなりので、私はここにいくつかの自由を取っている述語を持っていません)

またはpointfree

中のようになります。
f = (.enumFromTo 0).map 

私はPrologで十分に簡単にできるはずです。 Prologのmaplist/3は基本的にはすでにそれであるので、それは簡単な修正でなければなりません。私の定義は次のようになっているはずです:

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

しかし、私は空白に何を入れるべきかを本当に分かりません。ハスケルでは、私は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). 

しかし、それはちょうどそのような小さな問題のために本当にclunkyようです。

maplistのギャップをどのように埋めることができますか?私は間違った方法で問題に近づいていますか?

+1

間違ったアプローチだと思います。 Haskellは怠惰なので、リスト全体のマッピングは一度に存在しないので、リストのマッピングは問題ありません。 Prologでは、単に整数を更新する再帰的述語を実行する必要があります。 –

答えて

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

はHaskellコードによって暗示されるように、これは、いくつかのaためp :: Int -> aを想定

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)). 

としてプロローグに変換されます。

また、これは、具体的な( "グラウンド")呼び出し可能な2つの引数の述語Pと整数番号Nが与えられていることを前提としています。

別の可能性は、これは、すべてのX Sは、0 <= I <= NP(I,X))と認める

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

あるが成立します。 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

Picat自宅から述べたように、私は(ページの終わり近くに、実施例5を参照してください、PrologでNクイーン問題への解決策をコーディングしようとしていました)、私は同様の問題に直面した。最終的な結果は、いくつかの選択肢がコメントされています。

:- 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は、帰属変数の存在下でうまく動作しないことに注意する価値があります。

関連する問題