Prolog找到N个素数
我对Prolog的递归函数有问题。 我相信我没有正确实施,需要帮助。
我需要生成前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).
对于第一行,我如何使基本情况下,当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.
if-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
链接地址: http://www.djcxy.com/p/66931.html
上一篇: Prolog Find N prime numbers
下一篇: Why do circular references and recursion make my program fail?