【问题标题】:Prime factorization in prologprolog中的素数分解
【发布时间】:2014-07-03 01:55:06
【问题描述】:

我是 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]]).  

我得到'true',但是当我输入时:

factors(2,X).  

我得到'假'。

【问题讨论】:

    标签: prolog primes number-theory


    【解决方案1】:

    因为BasePow 还没有绑定到任何东西(它们是您传递的X 的一部分),所以您无法计算NewX(并且betweens 可能不起作用,或者)。

    【讨论】:

    • between/2 语句将具体值绑定到BasePow,因此可以计算NewX(如果is_list/2 没有问题的话)。如果它们没有被绑定,is/2 会引发异常。
    【解决方案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 创建了选择点。我删除了我的答案的那部分并将删减的部分放回代码中。

    【讨论】:

    • 我们还应该指出这个算法在计算上是多么糟糕。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多