prolog中的主要因子分解

时间:2014-05-14 20:18:25

标签: prolog primes number-theory

我是Prolog的新手。我读了这段代码,它找到了一个整数的素因子:

factors(1,[1]) :-
   true, !.
factors(X,[Factor1|T]) :-
   X > 0,
   between(2,X,Factor1), 
   NewX is X // Factor1, (X mod Factor1) =:= 0,
   factors(NewX,T), !.

并将其改为这一个:

factors(1,[[1,1]]) :-
   true, !.
factors(X,[Factor1|T]) :-
   X > 0,
   (  is_list(Factor1),
      length(Factor1, 2),
      Factor1 = [Base|A],
      A = [Pow], 
      between(2,X,Base),
      between(1,100,Pow), 
      NewX is X / (Base ** Pow),
      (X mod Base) =:= 0,
      (NewX mod Base) =\= 0
   ),
   factors(NewX,T), !.

第一个工作完美,但后者不响应查询。即当我进入时:

factors(2,[[2,1],[1,1]]).  

我得到'真',但是当我进入时:

factors(2,X).  

我得到'假'。

2 个答案:

答案 0 :(得分:2)

由于BasePow尚未绑定任何内容(它们是您传递的X的一部分),因此您无法计算{{1} (和NewX可能也不起作用。)

答案 1 :(得分:2)

当您输入factors(2,X)时,Factor1未绑定且is_list(Factor1)失败。

我认为你的代码

is_list(Factor1),
length(Factor1, 2),
Factor1 = [Base|A],
A = [Pow]

可以缩写为Factor1 = [Base,Pow]。由于Factor1未在其他任何地方使用,因此您可以将[Base,Pow]移到该子句的开头。

您可以省略true,此处无效。括号没有任何影响。所以你的代码可以写成:

factors(1,[[1,1]]) :- !.
factors(X,[[Base,Pow]|T]) :-
   X > 0,
   between(2,X,Base),
   between(1,100,Pow), 
   NewX is X / (Base ** Pow),
   (X mod Base) =:= 0,
   (NewX mod Base) =\= 0,
   factors(NewX,T), !.

在我的系统上(使用SICStus),必须使用

NewX is X // floor(Base ** Pow)

以防止NewX成为一个浮点数,当传递给mod作为参数时会导致错误。

编辑:我原来写道,最后一次剪辑没有效果。这不是真的,因为between/2创建了选择点。我删除了我的部分答案,并将其删回到代码中。