我是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).
我得到'假'。
答案 0 :(得分:2)
由于Base
和Pow
尚未绑定任何内容(它们是您传递的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
创建了选择点。我删除了我的部分答案,并将其删回到代码中。