如何在Prolog中动态创建质数列表?
Prolog实现动态收集1-50范围内的质数列表
核心问题分析
你之前的尝试错误在于用命令式编程的思路(动态修改列表)写Prolog代码——Prolog是逻辑编程语言,变量一旦绑定就无法修改,foreach的用途并非收集结果,且B is [0]写法有误(is仅用于算术运算,列表赋值要用=)。
Prolog中收集所有满足条件的结果到列表的标准方式是使用**findall/3**谓词,以下是具体解决方案:
第一步:修正质数判断规则
你的check_prime把1误判为质数(1不符合质数定义),先修正这个问题,保留你原有的实现逻辑:
check_prime(X) :- X > 1, % 质数必须大于1 X0 is X - 1, (X =:= 2 -> true; foreach(between(2, X0, T), X mod T =\= 0) -> true; false).
注:如果使用SWI-Prolog,需要先加载foreach库:
use_module(library(foreach)).
第二步:用findall/3收集质数列表
使用findall/3遍历1-50的所有数,收集其中符合check_prime的数到列表:
get_primes(Primes) :- findall(T, (between(1, 50, T), check_prime(T)), Primes).
findall(Result, Goal, List)的作用是:执行Goal对应的逻辑,将所有满足条件的Result值收集到List中。- 这里的
Goal是between(1,50,T), check_prime(T),即遍历1到50的每个数T,筛选出质数。
测试示例
在Prolog解释器中执行:
?- get_primes(P).
会得到结果:
P = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47].
更高效的质数判断实现(可选)
原有的foreach遍历到X-1效率较低,推荐用递归方式只遍历到√X即可:
check_prime(X) :- X > 1, \+ has_factor(X, 2). has_factor(X, F) :- F * F =< X, (X mod F =:= 0 ; F1 is F + 1, has_factor(X, F1)).
搭配同样的get_primes/1谓词即可使用。
内容的提问来源于stack exchange,提问作者Hayato
相关产品推荐
相关产品推荐

