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?