我试图在冰雹序列上实现各种形式的查询。
冰雹序列是具有以下属性的正整数序列:
- 1 被认为是序列的终止值。
- 对于任何偶数正整数 i,序列中 i 之后的值为 i/2。
- 对于任何奇正整数 j > 1,序列中 j 之后的值为 3j+1
查询可以
hailSequence (Seed,Sequence):其中 Sequence 是从给定的 Seed 生成的冰雹序列。
hailStone (M,N):其中 N 是冰雹序列中 M 之后的数字。例如,如果 M 为 5,则 N 应为 16,如果 M 为 20,则 N 应为 10,以此类推。
hailStorm (Seed,Depth,HailTree):其中 HailTree 是在指定深度的序列中可以在 Seed 之前的值树。
例子:
| ?- hailStorm(1,4,H).
H = hs(1,hs(2,hs(4,hs(8)))) ?
yes
| ?- hailStorm(5,3,H).
H = hs(5,hs(10,hs(3),hs(20))) ?
yes
现在我已经实现了前两个谓词:
hailSequence(1,[1]) :- !.
hailSequence(N,[N|S]) :- 0 is N mod 2, N1 is round(N / 2), hailSequence(N1,S).
hailSequence(N,[N|S]) :- 1 is N mod 2, N1 is (3 * N) + 1, hailSequence(N1, S).
hailStone(X,Y) :- nonvar(X), 0 is X mod 2, Y is round(X / 2).
hailStone(X,Y) :- nonvar(X), 1 is X mod 2, Y is (3 * X) + 1.
hailStone(X,Y) :- nonvar(Y), 1 is Y mod 3, T is round( (Y - 1) / 3), 1 is T mod 2, X is T.
对于hailStorm/2
谓词,我编写了以下代码,但它没有按预期工作:
make_hs1(S,hs(S)).
make_hs2(S,R,hs(S,make_hs1(R,_))).
make_hs3(S,L,R,hs(S,make_hs1(L,_),make_hs1(R,_))).
hailStorm(S,1,hs(S)) :- !.
hailStorm(S,D,H) :- nonvar(S), nonvar(D), 4 is S mod 6, S=\= 4, make_hs3(S,hailStorm(round((S-1)/3),D-1,_X),hailStorm(2*S,D-1,_Y),H).
hailStorm(S,D,H) :- nonvar(S), nonvar(D), make_hs2(S,hailStorm(2*S,D-1,_X),H).
输出:
| ?- hailStorm(5,2,H).
H = hs(5,make_hs1(hailStorm(2*5,2-1,_),_))
yes
这不是所需的输出,即
H = hs(5,hs(10)) ?