在Prolog中是否有相当于Haskell的enumFromTo?
我刚刚在序言开始了,我希望能执行以下任务:在Prolog中是否有相当于Haskell的enumFromTo?
做谓语
A(P,N,L)
使得对所有C
这是L
,P(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
中的空白?我以错误的方式接近问题吗?
回答:
-- % 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家表示(参见实施例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在属性变量存在的情况下效果不佳。
以上是 在Prolog中是否有相当于Haskell的enumFromTo? 的全部内容, 来源链接: utcz.com/qa/261575.html