yan*_*iou 2 list prolog clpfd clpz
我正在尝试在Prolog(SWI Prolog)中创建一个列表,并检查哪些数字是2的幂,然后查找列表中特定数字的次数(在此示例中,我试图查找该数字的次数)列表中有3个).举个例子,如果你问
?- check([0,2,3,-5,-2,1,8,7,4], MULT2, THREE).
Run Code Online (Sandbox Code Playgroud)
你应该看到
MULT2=[2,8,4]
THREE=1
Run Code Online (Sandbox Code Playgroud)
我第一次尝试找到一个解决方案是用头部搜索列表并执行头部mod 2 = 0来查找所有2次幂的数字,但是出了点问题我只得到"假"作为答案.
以下是您如何以逻辑上纯粹的方式找到"两个人的力量"!
使用sicstus-prolog 4.3.5,library(reif)和library(clpz):
:- use_module([library(reif), library(clpz)]). power_of_two_t(I, T) :- L #= min(I,1), M #= I /\ (I-1), call((L = 1, M = 0), T). % using (=)/3 and (',')/3 of library(reif)
示例查询1使用元谓词tfilter/3结合power_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
Run Code Online (Sandbox Code Playgroud)
以下是评论建议的更一般的查询:
?- 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.
Run Code Online (Sandbox Code Playgroud)
脚注1:上面显示的答案序列被刷新以表示呼叫的确定性.
脚注2:重现结果使用call_det/2,其定义如下:
call_det(G_0, Det) :- call_cleanup(G_0, Flag = set), ( nonvar(Flag) -> Det = true ; Det = false ).