如何在Prolog中动态创建列表?

问题描述 投票:0回答:1

我已经查看了无数其他类似的问题,但我还没有找到可行的解决方案,所以我问这个:

我有一个规则:

check_prime(X) :-
    X > 0,
    X0 is X - 1, 
    (X =:= 1 -> true; X =:= 2 -> true; foreach(between(2, X0, T), X mod T =\= 0) -> true; false).

然后我想跑步:

B is [0], 
foreach(between(1, 50, T), (check_prime(T) -> B2 = [B, T], write(B2); !)).

这成功地将 [0, primeNumber] 对写入控制台。我也可以这样做:

B is [0], foreach(between(1, 50, T), (check_prime(T) -> (write(T), write(", ")); !)).

实际上以一种漂亮的方式打印了所有内容,减去了列表的缺失以及末尾的额外逗号。

这个写入函数正在递归地处理 check_prime(T) 的解决方案,一次一个解决方案。我想列出所有这些解决方案,但无论我尝试什么,我要么无法获得对象持久性(写入的原子类似于_31415926),要么遇到各种错误。

由于每个素数都是递归找到的,因此如何动态创建素数列表?

编辑:

是的,这就是我正在使用的所有代码: enter image description here

enter image description here

我尝试过改变“if true”分支,但它仍然存在问题:

enter image description here enter image description here

enter image description here

prolog swi-prolog
1个回答
0
投票

如何动态创建素数列表?

使 check_prime 检查一个数字是否是素数(而不是其他):

check_prime(1).
check_prime(2).
check_prime(X1) :-
    X1 > 2,
    succ(X0, X1),
    forall(between(2, X0, N), \+ (0 is X1 mod N)).

然后用它来制作素数列表,例如:

?- findall(X, (between(1, 50, X), check_prime(X)), Primes).
Primes = [1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

primes_to(X, Primes) :-
    numlist(1, X, Nums),
    include(check_prime, Nums, Primes).

?- primes_to(50, Primes).
Primes = [1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

如果您确实想要递归地而不是方便地执行此操作,则构建器会在计数器为 0 时将某些内容添加到素数列表中,而如果计数器不是 0 则不会:

primes_to(0, []).

primes_to(Counter, [Counter|Primes]) :-
    check_prime(Counter),
    Counter0 is Counter - 1,
    primes_to(Counter0, Primes).

primes_to(Counter, Primes) :-
    \+ check_prime(Counter),
    Counter0 is Counter - 1,
    primes_to(Counter0, Primes).


?- primes_to(50, Primes).
Primes = [47, 43, 41, 37, 31, 29, 23, 19, 17, 13, 11, 7, 5, 3, 2, 1]
© www.soinside.com 2019 - 2024. All rights reserved.