我有序言的递归函数的一个问题。 我相信我没有实现它的权利和需要帮助。
我需要生成的前N素数并以列表返回。 生成素数是不是一个问题,而是一个列表生成是我的问题。
这是相关代码的一部分:
genList(_, 0, _).
genList(X, N, PrimeList, PrimeList):-
N > 0,
isprime(X),
X1 is X +1,
N1 is N -1,
genList(X1,N1,[X|PrimeList], [X|PrimeList]),!.
genList(X, N, PrimeList, PrimeList):-
N>0,
\+isprime(X),
X1 is X + 1,
genList(X1,N,PrimeList, PrimeList).
这是我键入到Prolog的解释:
genList(1,N, [],L).
对于1号线,如何让我的基本情况,例如,当N=0
,我停止递归? 这个对吗?
至于接下来的2项条款,我有在逻辑编程的思维难度。 我明显感觉到,这不是逻辑的编程风格。
我想说的是,当isPrime(X)
失败,我们继续下一个数字,没有保存任何,但是当isPrime(X)
为真,那么我们递归,继续下一个号码,节省X
。
我该怎么做,在Prolog的?
首先,你不应该需要4个参数,以你的主谓如果你只想要两个。 在这里,你想第一个素数最多的列表N
。 因此,对于一个参数N
的列表和参数应该是足够了:
primeList(N, L) :-
% eventually in the body a call to a worker predicate with more arguments
现在这里,你的逻辑,在这些方面解释说:
primeList(N, [N|L]) :-
% If we're not at the base case yet
N > 0,
% If N is a prime
isPrime(N),
NewN is N - 1,
% Let's recurse and unifie N as the head of our result list in the head
% of the predicate
primeList(NewN, L).
primeList(N, L) :-
% Same as above but no further unification in the head this time.
N > 0,
% Because N isn't a prime
\+ isPrime(N),
NewN is N - 1,
primeList(NewN, L).
为此你不得不添加的基本情况
primeList(0, []).
你可以重写以削减如下:
primeList(0, []) :- !.
primeList(N, [N|L]) :-
isPrime(N),
!,
NewN is N - 1,
primeList(NewN, L).
primeList(N, L) :-
NewN is N - 1,
primeList(NewN, L).
这里是你的意思写的:
genList(N, L) :- genList(2, N, L, []).
genList(X, N, L, Z):- % L-Z is the result: primes list of length N
N > 0 ->
( isprime(X) -> L=[X|T], N1 is N-1 ; L=T, N1 is N ),
X1 is X + 1,
genList(X1,N1,T,Z)
;
L = Z.
如果- then-else结构体现了削减。 而你是正确的,它本质上是一个函数式编程风格。
我们可以引入一个小的转折它,不允许请求0素数(有没有一点也无妨),让我们也找回了最后生成素:
genList(1, [2], 2) :- !.
genList(N, [2|L], PN) :- N>1, L=[3|_], N2 is N-2, gen_list(N2, L, [PN]).
gen_list(N, L, Z) :- L=[P|_], X is P+2, gen_list(X, N, L, Z).
gen_list(X, N, L, Z) :- % get N more odd primes into L's tail
N > 0 ->
( isprime(X) -> L=[_|T], T=[X|_], N1 is N-1 ; L=T, N1 is N ),
X1 is X + 2,
gen_list(X1,N1,T,Z)
;
L = Z. % primes list's last node
运行:
?- genList(8,L,P).
L = [2, 3, 5, 7, 11, 13, 17, 19]
P = 19
这也使我们停下来的地方,我们停止了,而不是从头开始了,点继续素数代:
?- L = [3|_], gen_list(8, L, Z), Z=[P10|_], writeln([2|L]),
gen_list(10, Z, Z2), Z2=[P20], writeln(Z).
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29|_G1037]
[29,31,37,41,43,47,53,59,61,67,71]
P10 = 29
P20 = 71