双因子swi-prolog

时间:2018-04-22 20:12:28

标签: prolog

求助我需要找((2n-1)!!)\(2n)!!但我只知道如何写因子而不是双倍。

protocol Sound {
    let title: String { get }
    let length: TimeInterval { get }
}

1 个答案:

答案 0 :(得分:2)

如果您在double factorial上查找维基百科条目,您可以轻松找到基本案例的两个候选人:0 !! = 1和1 !! = 1.根据数字n是奇数,甚至在计算n时你会得到其中一个基本情况!!递归地,因为在递归规则中,n减少2而不是1(与n!相比)。你可以像这样在Prolog中表达:

doublefactorial(0,1).
doublefactorial(1,1).
doublefactorial(N,F) :-
   N > 1,
   N2 is N-2,
   doublefactorial(N2,F1),
   F is N * F1.

如果查询此谓词,您将获得所需的结果:

?- doublefactorial(0,F).
F = 1 ;
false.

?- doublefactorial(1,F).
F = 1 ;
false.

?- doublefactorial(2,F).
F = 2 ;
false.

?- doublefactorial(3,F).
F = 3 ;
false.

?- doublefactorial(4,F).
F = 8 ;
false.

?- doublefactorial(5,F).
F = 15 ;
false.
.
.
.

但是,由于使用>/2is/2,此谓词只能用于一个方向:

?- doublefactorial(N,10395).
ERROR: >/2: Arguments are not sufficiently instantiated

?- doublefactorial(N,F).
N = 0,
F = 1 ;
N = F, F = 1 ;
ERROR: >/2: Arguments are not sufficiently instantiated

如果您想在所有方向使用谓词,您可以选择使用CLP(FD):

:- use_module(library(clpfd)).  

doublefactorial2(0,1).
doublefactorial2(1,1).
doublefactorial2(N,F) :-
   N #> 1,
   N2 #= N-2,
   F #= N * F1,
   doublefactorial2(N2,F1).

?- doublefactorial2(N,10395).
N = 11 ;
false.

?- doublefactorial2(N,46080).
N = 12 ;
false.

?- doublefactorial2(N,F).
N = 0,
F = 1 ;
N = F, F = 1 ;
N = F, F = 2 ;
N = F, F = 3 ;
N = 4,
F = 8 ;
N = 5,
F = 15 ;
N = 6,
F = 48 ;
N = 7,
F = 105 ;
N = 8,
F = 384 ;
N = 9,
F = 945 ;
.
.
.

注意目标F #= N * F1现在如何放在递归目标之前,从而使谓词尾递归,因为该方程现在作为约束传播。有关更多信息,请参阅CLP(FD)上的SWI-Prolog文档。

计算(2n)!! /(2n-1)!!或(2n-1)!! /(2n)!!对于特定的n,您可以像这样查询谓词:

?- N=5, X #= 2*N, doublefactorial2(X,F1), Y #= 2*N-1, doublefactorial2(Y,F2), RESULT is F1/F2.
N = 5,
X = 10,
F1 = 3840,
Y = 9,
F2 = 945,
RESULT = 4.063492063492063 ;
false.

?- N=5, X #= 2*N, doublefactorial2(X,F1), Y #= 2*N-1, doublefactorial2(Y,F2), RESULT is F2/F1.
N = 5,
X = 10,
F1 = 3840,
Y = 9,
F2 = 945,
RESULT = 0.24609375 ;
false.

请注意,结果实际上是使用is/2计算的。这是因为,一般来说,结果不是整数而是有理数,因此您可以使用CLP(Q)将结果作为分数得出:

?- use_module(library(clpq)).
% library(clpq) compiled into clpq 0.08 sec, 1,189 clauses
true.

?- N=5, X #= 2*N, doublefactorial2(X,F1), Y #= 2*N-1, doublefactorial2(Y,F2), {RESULT = F1/F2}.
N = 5,
X = 10,
F1 = 3840,
Y = 9,
F2 = 945,
RESULT = 256 rdiv 63 ;
false.

?- N=5, X #= 2*N, doublefactorial2(X,F1), Y #= 2*N-1, doublefactorial2(Y,F2), {RESULT = F2/F1}.
N = 5,
X = 10,
F1 = 3840,
Y = 9,
F2 = 945,
RESULT = 63 rdiv 256 ;
false.

有关详细信息,请参阅CLP(Q)上的SWI-Prolog文档。由于使用了CLP(FD),您还可以查询n的范围,例如1到5:

?- N in 1..5, X #= 2*N, doublefactorial2(X,F1), Y #= 2*N-1, doublefactorial2(Y,F2), {RESULT = F1/F2}.
N = Y, Y = F2, F2 = 1,
X = F1, F1 = RESULT, RESULT = 2 ;
N = 2,
X = 4,
F1 = 8,
Y = F2, F2 = 3,
RESULT = 8 rdiv 3 ;
N = 3,
X = 6,
F1 = 48,
Y = 5,
F2 = 15,
RESULT = 16 rdiv 5 ;
N = 4,
X = 8,
F1 = 384,
Y = 7,
F2 = 105,
RESULT = 128 rdiv 35 ;
N = 5,
X = 10,
F1 = 3840,
Y = 9,
F2 = 945,
RESULT = 256 rdiv 63 ;
false.