I've just been starting out in Prolog and I was hoping to perform the following task:
Make a predicate
a
such that for allA(P,N,L)
which is nth element ofC
,L
.
Basically I want to perform a map on the range P(N,C)
.
In Haskell, the language I am most familiar with, this would look like
[0..N]
(Haskell doesn't quite have predicates so I'm taking some liberties here)
or in pointfree
f p n = map(p)[0..n]
And it seems like I should be able to do it in Prolog easily enough. Prolog's f = (.enumFromTo 0).map
is basically already that so it should be a trivial modification. My definition should look something like:
maplist/3
However I can't really figure out what to put in the blank. In Haskell I would use a function like A(P,N,L) :- maplist(P, ??? , L).
, but it seems that such a thing doesn't exist in Prolog. The closes equivalent would be enumFromTo
, but that isn't a list so I can't use for between/3
.
Alternatively I could make my own range predicate.
The first thing I tried was:
maplist
But I can't get that to resolve at all. I also tried
range(0,[0]).
range(N,[N|T]) :- range(N-1,T).
A(P,N,L) :- range(N,rangeN), maplist(P, rangeN, L).
But that just seems really clunky for such a small problem.
How might I fill in the gap in my range(N,L):-findall(X,between(0,N,X),L),sort(L,L).
A(P,N,L) :- range(N,rangeN), maplist(P, rangeN, L).
? Am I approaching the problem in the wrong way?
答案 0 :(得分:2)
Firebase push Notifications
被翻译成Prolog为
-- % f p n = map (p) [0..n] = [p 0, p 1, p 2, ..., p n]
这假定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
,如Haskell代码所暗示的那样。
这也假设给你一个具体的(" ground")可调用的双参数谓词a
和一个整数P
。
另一种可能性是
N
这会找到所有g(P,N,L):- findall(X, (between(0, N, I), call(P,I,X)), L).
,以便(X
和 0 <= I <= N
)成立。
在SWI-Prolog中测试:
P(I,X)
答案 1 :(得分: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在存在属性变量的情况下效果不佳。