2

我正在尝试在 Prolog (SWI Prolog) 中创建一个列表并检查哪些数字是 2 的幂,然后查找特定数字在列表中的次数(在此示例中,我试图找到该数字的次数3 在列表中)。例如,如果您问

?- check([0,2,3,-5,-2,1,8,7,4], MULT2, THREE).

你应该看到

MULT2=[2,8,4] 
THREE=1 

我第一次尝试找到解决方案是使用 head 搜索列表并执行 head mod 2 = 0 以查找所有 2 的幂的数字,但出现问题,我只得到“假”作为答案。

4

2 回答 2

5

以下是您如何以纯逻辑的方式找到“二的幂”!

使用 4.3.5library(reif)library(clpz)

:- use_module([ library(reif) , library(clpz) ])。

power_of_two_t(I, T) :-
   L #= min(I,1),
   M #= I /\ (I-1),
   调用((L = 1,M = 0),T)。% 使用 (=)/3 和 (',')/3 of library(reif)

使用元谓词结合的示例查询1tfilter/3power_of_two_t/2

?- tfilter(power_of_two_t, [0,2,3,-5,-2,1,8,7,4], Ps).
Ps = [2,1,8,4].                  % succeeds deterministically

这是评论建议的更一般的查询:

?- tfilter(power_of_two_t, [X], Ps).
   Ps = [X], 0#=X/\_A, _A+1#=X, X in 1..sup, _A in 0..sup
;  Ps = [], dif(_A,0), _A#=X/\_B, _B+1#=X, X in 1..sup, _B in 0..sup
;  Ps = [], dif(_A,1), _A#=min(X,1), _B#=X/\_C, _C+1#=X, X#>=_A, _A in inf..1.

脚注 1:上面显示的应答序列经过整理以表明呼叫的确定性。

脚注 2:要重现结果,请使用call_det/2如下定义:

call_det(G_0, Det) :-
   call_cleanup(G_0,标志=设置),
   (非变量(标志)
   -> 检测 = 真
   ; 检测 = 假
   )。

于 2015-05-13T09:48:35.047 回答
1

在一个谓词中执行两个如此不同的任务是一件奇怪的事情。您可能应该有两个单独的谓词,一个用于计算 2 的幂数,一个用于计算 3 的次数。然后您可以将它们组合在一个谓词中,例如:

check(Nums, MULT2, THREE) :-
    count2powers(Nums, MULT2),
    count3s(Nums, THREE).

之后,您可以进一步分解并有一个单独的谓词来检查一个数字是否是 2 的幂:

is2power(1).
is2power(N) :-
    N > 0,
    N2 is N // 2,
    N2 * 2 =:= N,
    is2power(N2).

这是基本的软件工程,通过这种方式,您可以逐步构建您的程序,并且您将能够提出更具体和更有意义的问题,而不仅仅是“整个程序返回错误”。

于 2014-02-03T02:02:24.290 回答