【问题标题】:Prolog, check if term is power of 2Prolog,检查项是否为 2 的幂
【发布时间】:2013-10-30 07:12:00
【问题描述】:

我编写了以下代码,应该符合我的逻辑,但它没有。

我应该检查给定的术语是否是二的幂。例如s(s(s(nul))) 应该返回 false,s(s(s(s(nul))) 应该返回 true。

substractWhileY(X,0,rezult).
substractWhileY(s(X),Y,rezult):-
   Y > 0, number is 1,  substractWhileY(X,Y - number, rezult).

degreeOftwo(X):-
   substractWhileY(X,2,rezult),
   pagalba(X, 2, rezult).
calculateAnswer(X, currentCounter, currentValue):-
   currentCounter is currentCounter * 2,
   substractWhileY(currentValue, currentCounter , rezult),
   rezult\= null,
   calculateAnswer(X, currentCounter , rezult).

我的想法是检查给定的 therm 是否是任意二的度数,如果不是,则不是二度数。

对于数字,它应该像这样工作。例如我给数字 8。

First time it checks if 8 - 2 = 0.
second time if 8 - 4 = 0.
third time if 8 - 8 = 0.

所以是两个的 8 id 幂。

也许其他解决方案会更好,所以感谢您的帮助。

【问题讨论】:

  • 变量以大写开头!
  • 2 度是什么意思? 0, 2, 4, 8, 16, ...?
  • 是的,您记下的正是这些数字。我不知道怎么用英文正确称呼它
  • 那么它的公式是什么? 2^n 有点道理,但 2^0 是 1,而不是 0....
  • @Riku,那将是“2 的幂”。而“热”可能是指“术语”。 :)

标签: prolog successor-arithmetics


【解决方案1】:

假设您正在寻找数字 1、2、4、8...,或者换句话说,2^0、2^1、2^2、2^3、...,那么一个解决方案是确定性的可能是:

two_power_n(s(X)) :-
    two_power_n_minus_one(X). 

two_power_n_minus_one(0).
two_power_n_minus_one(s(X)) :-
    half(s(s(X)), s(Y)),
    two_power_n_minus_one(Y).

half(0, 0).
half(s(s(X)), s(Y)) :-
    half(X, Y).

我不认为这个解决方案是最优的。

【讨论】:

  • @Riku 所以名字不够明显?你有什么不明白的地方,特别是让我解释得更好?
  • 后继算术中零的通用约定是0 而不是nul。除此之外,还有不使用sum/3add/3 的理由吗?
  • @false 我想绝对没有理由不使用sum/3add/3,除了我不知道它们的存在。使用sum/3add/3 的解决方案会如何?
  • 也许我不明白一些东西,但是将任何东西传递给 two_power_n() 对我来说总是返回 false。
  • @Boris: 使用sum/3 确实很有意义,因为这说明了单个谓词如何服务于多种用途,而half 建议使用非常规范的阅读方式。
【解决方案2】:

利用计算机中用于有符号整数的二进制补码表示的属性,很容易确定一个定点二进制补码整数是否是 2 的幂:

pow2( X ) :-     % X is a power of 2, if...
  X > 0 ,        % - X is > 0 , and ...
  X is X /\ (-X) % - A bitwise AND of X and its 2s complement yields X
  .              % Easy!

不需要递归,只是有点玩弄。

鉴于此,解决方案很简单。只需遍历嵌套结构s/1 并计算其深度/长度。然后判断它是否是 2 的幂。

IsPowerOf2( S ) :- nested_depth(S,0,D) , pow2(D) .

nested_depth( nul  , D , D ).
nested_depth( s(X) , T , D ) :-
  T1 is T+1 ,
  nested_depth(X)
  .

【讨论】:

  • 确实是显而易见的解决方案
【解决方案3】:

Boris 的答案肯定更完整/正确 (+1),而且我早于他的 half/2 谓词。但是您的问题的解决方案看起来更简单:

pow_of_two(s(nul)).
pow_of_two(X) :-
    half(X, H),
    pow_of_two(H).

【讨论】:

  • 它将进入pow_of_two(nul) 的无限循环(我现在定义它的方式,但这可以修复)。我有额外谓词的唯一原因是这个解决方案是不确定的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 2014-02-26
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
相关资源
最近更新 更多