您的代码对于 prolog 来说有点不寻常,但(prime(1) 除外)它可以工作。
这是您的谓词的解决方案:
nextprime(N,N):-
prime(N),
!.
nextprime(P, Prime):-
PP is P+1,
nextprime(PP,Prime).
nthprime(1, 2).
nthprime(N, Prime):-
N>1,
NN is N-1,
nthprime(NN, PrevPrime),
PP is PrevPrime+1,
nextprime(PP, Prime).
?- nthprime(1,P).
P = 2 ;
false.
?- nthprime(2,P).
P = 3 ;
false.
?- nthprime(3,P).
P = 5 ;
false.
它的工作原理如下:已知第一个素数是2(nthprime(1, 2).)。对于大于 1 的每个其他数字 N,获取前一个质数 (nthprime(NN, PrevPrime)),加 1 直到遇到质数。 add 1 部分是通过帮助谓词nextprime/2 完成的:对于给定的数字P,它将检查该数字是否为质数。如果是,它会返回这个数字,否则它将调用自己以获得下一个更高的数字 (nextprime(PP,Prime)) 并转发输出。爆炸! 被称为切割其他选择分支。所以如果你曾经遇到过一个质数,你就不能回去尝试另一条路了。
要对其进行测试,您可以向?- nthprime(N,P). 询问给定的N。或者要一次检查多个答案,让我们引入一个辅助谓词 nthprimeList/2,它为 firstlist 中的每个项目调用 nthprime/2 并将“输出”放入一个列表中:
nthprimeList([],[]).
nthprimeList([N|TN],[P|TP]):-
nthprime(N,P),
nthprimeList(TN,TP).
?- nthprimeList([1,2,3,4,5,6,7,8,9],[P1,P2,P3,P4,P5,P6,P7,P8,P9]).
P1 = 2,
P2 = 3,
P3 = 5,
P4 = 7,
P5 = 11,
P6 = 13,
P7 = 17,
P8 = 19,
P9 = 23;
false.