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
将引发异常。我们还应该指出此算法在计算上有多糟糕。我们还应该指出此算法在计算上有多糟糕。