prolog中的素因子分解

prolog中的素因子分解,prolog,primes,number-theory,Prolog,Primes,Number Theory,我不熟悉序言。我读过这段代码,它可以找到整数的素数因子: 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,[F

我不熟悉序言。我读过这段代码,它可以找到整数的素数因子:

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), !.
第一个很好,但是后者不响应查询。i、 e.当我进入时:

factors(2,[[2,1],[1,1]]).  
factors(2,X).  
我得到“真”,但当我进入时:

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

我得到“false”。

因为
Base
Pow
还没有绑定到任何东西(它们是您传递的
X
的一部分),您无法计算
NewX
(并且
之间的
也可能不起作用)。

因为
Base
Pow
还没有绑定到任何东西(它们是您传递的
X
的一部分),您无法计算
NewX
(并且
之间的
也可能不起作用)。

当您输入
因子(2,X)
时,
因子1
未绑定且
是列表(因子1)
失败

我想你的密码

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
时导致错误


编辑:我最初写的是最后一次削减没有效果。这不是真的,因为
在/2之间
创建了选择点。我删除了我答案的那部分,并将削减放回代码中。

当你输入
因子(2,X)
时,
因子1
没有绑定并且
是列表(因子1)
失败

我想你的密码

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
创建了选择点。我删除了答案的这一部分,将剪切部分放回代码中。

between/2
语句将具体值绑定到
Base
Pow
,因此
NewX
可以被计算(如果
is\u list/2
没有问题的话)。如果它们没有绑定,
is/2
将引发异常。
between/2
语句将具体值绑定到
Base
Pow
,因此可以计算
NewX
(如果
is\u list/2
没有问题的话)。如果它们没有绑定,
is/2
将引发异常。我们还应该指出此算法在计算上有多糟糕。我们还应该指出此算法在计算上有多糟糕。