我正在尝试用数字1,2,3,...,N填充给定长度N的列表。
我认为这可以这样做:
create_list(N,L) :-
length(L,N),
forall(between(1,N,X), nth1(X,L,X)).
但是,这似乎不起作用。谁能说我做错了什么?
答案 0 :(得分:1)
我现在没有可用的prolog翻译,但不会像...那样......
isListTo(N, L) :- reverse(R, L), isListFrom(N, R).
isListFrom(0, []).
isListFrom(N, [H|T]) :- M is N - 1, N is H, isListFrom(M, T).
反转可以通过使用例如http://www.webeks.net/prolog/prolog-reverse-list-function.html
所以跟踪isListTo(5,[1,2,3,4,5])......
isListTo(5, [1, 2, 3, 4, 5])
<=> isListFrom(5, [5, 4, 3, 2, 1])
<=> 5 is 5 and isListFrom(4, [4, 3, 2, 1])
<=> 4 is 4 and isListFrom(3, [3, 2, 1])
<=> 3 is 3 and isListFrom(2, [2, 1])
<=> 2 is 2 and isListFrom(1, [1])
<=> 1 is 1 and isListFrom(0, [])
QED
由于PROLOG不仅会评估真相,而且会找到令人满意的解决方案,因此这应该有效。我知道这是一个与你正在尝试的方法截然不同的方法,如果你的问题是专门关于在PROLOG中做循环的话,请道歉(如果是这种情况,可能会重新标记问题?)。
答案 1 :(得分:1)
首先要做的事情:使用clpfd!
:- use_module(library(clpfd)).
在下面我提出的zs_between_and/3
,(与我之前的回答相比)提供了更多功能。
首先,让我们先定义一些辅助谓词!
equidistant_stride([] ,_).
equidistant_stride([Z|Zs],D) :-
equidistant_prev_stride(Zs,Z,D).
equidistant_prev_stride([] ,_ ,_). % internal predicate
equidistant_prev_stride([Z1|Zs],Z0,D) :-
Z1 #= Z0+D,
equidistant_prev_stride(Zs,Z1,D).
让我们运行一些查询来获取equidistant_stride/2
:
?- Zs = [_,_,_], equidistant_stride(Zs,D).
Zs = [_A,_B,_C], _A+D#=_B, _B+D#=_C.
?- Zs = [1,_,_], equidistant_stride(Zs,D).
Zs = [1,_B,_C], _B+D#=_C, 1+D#=_B.
?- Zs = [1,_,_], equidistant_stride(Zs,10).
Zs = [1,11,21].
到目前为止,非常好......转到实际的#34;填充列表&#34;谓词zs_between_and/3
:
zs_between_and([Z0|Zs],Z0,Z1) :-
Step in -1..1,
Z0 #= Z1 #<==> Step #= 0,
Z0 #< Z1 #<==> Step #= 1,
Z0 #> Z1 #<==> Step #= -1,
N #= abs(Z1-Z0),
( fd_size(N,sup)
-> true
; labeling([enum,up],[N])
),
length(Zs,N),
labeling([enum,down],[Step]),
equidistant_prev_stride(Zs,Z0,Step).
有点巴洛克式,我必须承认......
与我的previous answer相比,让我们看看获得了哪些功能!
?- zs_between_and(Zs,1,4). % ascending consecutive integers
Zs = [1,2,3,4]. % (succeeds deterministically)
?- zs_between_and(Zs,3,1). % descending consecutive integers (NEW)
Zs = [3,2,1]. % (succeeds deterministically)
?- zs_between_and(Zs,L,10). % enumerates fairly
L = 10, Zs = [10] % both ascending and descenting (NEW)
; L = 9, Zs = [9,10]
; L = 11, Zs = [11,10]
; L = 8, Zs = [8,9,10]
; L = 12, Zs = [12,11,10]
; L = 7, Zs = [7,8,9,10]
...
?- L in 1..3, zs_between_and(Zs,L,6).
L = 3, Zs = [3,4,5,6]
; L = 2, Zs = [2,3,4,5,6]
; L = 1, Zs = [1,2,3,4,5,6].
想要更多?我们走了!
?- zs_between_and([1,2,3],From,To).
From = 1, To = 3
; false.
?- zs_between_and([A,2,C],From,To).
A = 1, From = 1, C = 3, To = 3 % ascending
; A = 3, From = 3, C = 1, To = 1. % descending
答案 2 :(得分:1)
如果我理解正确,内置的谓词numlist / 3就可以了。 http://www.swi-prolog.org/pldoc/man?predicate=numlist/3