CLP(FD)-ing Fibonacci Lukas数字的同时递归可能吗?

时间:2016-03-28 14:29:16

标签: prolog clpfd

有一些instances,其中递归谓词可以是CLP(FD) - 具有谓词转向双向的好处。这种方法有哪些限制?例如,以下computation CLP(FD)-fied:

Fn: n-th Fibonacci Number
Ln: n-th Lucas Number (starting with 2)

通过这个加倍的递归步骤:

F2n = Fn*Ln
L2n = (5*Fn^2+Ln^2)//2

这个递增的递归步骤:

Fn+1 = (Fn+Ln)//2
Ln+1 = (5*Fn+Ln)//2

传统的Prolog realization已经从n到Fn工作。这可以变成CLP(FD)程序,保持快速递归并同时使其双向,例如找出Fn = 377的索引n吗?如果有,怎么样?如果不是为什么?

再见

1 个答案:

答案 0 :(得分:4)

是的,可以通过约束值来完成。您也可以将递归移动为尾递归,尽管不需要获得解决方案:

multiTooltipTemplate : "<%=datasetLabel%> : <%=value%>"

将屈服:

fibluc(0, 0, 2).
fibluc(1, 1, 1).
fibluc(N, F, L) :-
    N in 2..1000,        % Pick a reasonable value here for 1000
    [F, L] ins 1..sup,
    N rem 2 #= 1,
    M #= N-1,
    F #= (F1 + L1) // 2,
    L #= (5*F1 + L1) // 2,
    fibluc(M, F1, L1).
fibluc(N, F, L) :-
    N in 2..1000,        % Pick a reasonable value here for 1000
    [F, L] ins 1..sup,
    N rem 2 #= 0,
    M #= N // 2,
    F #= F1 * L1,
    L #= (5*F1*F1 + L1*L1) // 2,
    fibluc(M, F1, L1).

可以修改此值,以便在?- fibluc(10, X, Y). X = 55, Y = 123 ; false. ?- fibluc(N, 55, Y). N = 10, Y = 123 ; false. ?- fibluc(N, X, 123). N = 10, X = 55 ; false. ?- fibluc(N, 55, 123). N = 10 ; false. ?- fibluc(N, 55, 125). false. ?- fibluc(N, X, Y). N = X, X = 0, Y = 2 ; N = X, X = Y, Y = 1 ; N = 3, X = 2, Y = 4 ; N = 7, X = 13, Y = 29 ; N = 15, X = 610, Y = 1364 ; N = 31, X = 1346269, Y = 3010349 ; N = 63, X = 6557470319842, Y = 14662949395604 ; ... 未实例化时生成N值增加的结果。
这是一个定时的复合查询示例,在Linux下的SWI Prolog 7.1.33中运行:

N

使用上面相同的代码和相同的复合查询使用SWI Prolog 7.2.3,代码确实会很长时间。我等了至少15分钟没有终止。它现在还在运行......我可以在早上检查它。 :)

然而,我确实重新安排了上面的代码,将递归调用移回原始代码所具有的位置,如下所示:

?- time((fibluc(100, X, Y), fibluc(N, X, Z))).
% 11,337,988 inferences, 3.092 CPU in 3.100 seconds (100% CPU, 3666357 Lips)
X = 354224848179261915075,
Y = Z, Z = 792070839848372253127,
N = 100 ;
% 1,593,620 inferences, 0.466 CPU in 0.468 seconds (100% CPU, 3417800 Lips)
false.

?-

在这种情况下,返回了有利的结果:

fibluc(0, 0, 2).
fibluc(1, 1, 1).
fibluc(N, F, L) :-
    N in 2..1000,        % Pick a reasonable value here for 1000
    [F, L] ins 1..sup,
    N rem 2 #= 1,
    M #= N-1,
    fibluc(M, F1, L1),
    F #= (F1 + L1) // 2,
    L #= (5*F1 + L1) // 2.
fibluc(N, F, L) :-
    N in 2..1000,        % Pick a reasonable value here for 1000
    [F, L] ins 1..sup,
    N rem 2 #= 0,
    M #= N // 2,
    fibluc(M, F1, L1),
    F #= F1 * L1,
    L #= (5*F1*F1 + L1*L1) // 2.

请注意,CLP(FD)的性能在不同的Prolog解释器之间可能会有很大差异。有趣的是,使用SWI Prolog,处理尾递归案例的能力暂时存在于版本7.1.33。