Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 二项式系数_Prolog_Binomial Coefficients_Swi Prolog For Sharing - Fatal编程技术网

Prolog 二项式系数

Prolog 二项式系数,prolog,binomial-coefficients,swi-prolog-for-sharing,Prolog,Binomial Coefficients,Swi Prolog For Sharing,为什么它返回false 任务是:编写递归过程C(M,N)(0≤ M≤ n)使用此公式计算二项式系数: bc(0,N,R,R):- N>0,R is 1,!. bc(M,0,R,R):- M>0,R is 1,!. bc(N,N,R,R):- R is 1,!. bc(M,N,R,R1):- M1 is M - 1, N1 is N - 1, bc(M1,N1,R,R2), bc(M1,N,R,R3), R1 is R2+R3. 附言:我

为什么它返回false

任务是:编写递归过程
C(M,N)(0≤ M≤ n)
使用此公式计算二项式系数:

bc(0,N,R,R):- N>0,R is 1,!.
bc(M,0,R,R):- M>0,R is 1,!.
bc(N,N,R,R):- R is 1,!.
bc(M,N,R,R1):- 
    M1 is M - 1, 
    N1 is N - 1, 
    bc(M1,N1,R,R2),
    bc(M1,N,R,R3),
    R1 is R2+R3.

附言:我使用在线编译器SWISH。

首先,让我们正确说明二项式系数的公式。
c(M,N)
的常规定义是
M>=N>=0
,而不是如上所述的
N>=M>=0
。这一点很重要,因为给出的公式如下:

C(m,0)=C(0,n)=C(n,n)=1c(m,n)=C(m−1,n−1) +C(m)−1,n)

假设
0≤ N≤ m
,不是所述内容(
0≤ M≤ n
)。所以它是不正确的(要么是给出的不正确,要么是你写的不正确)。此外,
C(0,n)
不是有效的系数,除非
n=0
。因此,这种情况没有意义,可以省略。它已经被
C(m,0)
所覆盖

问题的不正确表述可能是导致结果“错误”的主要原因

C(n,0)=C(n,n)=1
将包含在以下基本(非递归)情况中:

然后根据给定公式递归处理更一般的情况:

bc(N, 0, 1) :- N #>= 0.
bc(N, N, 1) :- N #> 0.    % The N = 0 case is already covered in the first base case
编写Prolog谓词时的几个原则:

  • 确保你的问题陈述准确无误。这听起来很明显,但在本案中是个问题

  • 使用CLP(FD)进行整数推理。Prolog所涉及的是更多的关系。使用
    is/2
    更为必要。例如,如果
    Y
    未绑定,
    X是Y*2
    将生成实例化错误。但是
    X#=Y*2
    将产生潜在的解决方案。如果由于任意要求而必须使用
    is/2
    ,则可以将其替换回中

  • 在谓词子句中应用使它们相互排斥的约束。也就是说,除非它是您想要的,否则对于给定的解决方案,不要允许谓词以多种方式成功。特别是,使你的不同条款不重叠。例如,如果您有一个谓词,其中第一个参数是一个自然数(非负整数),并且基本情况是
    foo(0,1)。
    ,那么在递归情况下
    foo(N,R):-
    您需要一个约束
    N>0
    N#>0
    ,假设在递归情况下没有其他可能需要和/或不同的副作用或其他参数

  • 在所需的解决方案空间中约束或绑定变量的次数越多,代码就越不会偏离尝试无效解决方案的选项,并且在最坏的情况下,不会因为缺少对此类非解决方案选项的绑定而终止。例如,在这个问题中,我们添加了约束
    R#>=M
    ,这在
    N>0
    N
    时是正确的。如果没有这个约束,Prolog将探索
    R
    无限的情况,在某些情况下会导致不终止

运行查询:

bc(M, N, R) :-
    N #> 0,        % The N = 0 case is already covered in the first base case
    M #> N,        % The M = N case is already covered in the second base case
    R #>= M,       % This constraint prevents unbounded search in non-solution space
    M1 #= M - 1,   % The rest of this is just the given formula
    N1 #= N - 1,
    bc(M1, N1, R1),
    bc(M1, N, R2),
    R #= R1 + R2.
等等

通过使用CLP(FD)运算符,您还可以运行如下查询:

| ?- bc(3,2,R).

R = 3 ? ;

no
| ?- bc(4,2,R).

R = 6 ? ;

no
| ?-
而且

| ?- bc(4,X,6).

X = 2 ? ;

no
| ?-

为什么需要4个参数?第四个似乎是多余的,可能会给你带来麻烦。把它扔掉。您的
bc(N,N,…)
案例应该具有条件
N>0
,这样它的真值就不会与其他两个基本案例重叠。而
bc(M,N,…)
应该具有
M>N
的条件,因为这就是这种情况的目的。如果你的条件设置正确,你就不需要削减。你能用自己的话解释一下为什么你认为上述尝试会产生正确的结果吗?您运行的查询是什么?bc(2,4,RES,0),从那里开始:M=2,N=4,Result,每个结果。我需要计算一个参数为M的二项式系数,您的代码中有两个输入错误:目标
N>0
M>N
。使用这些示例查询
?-bc(4,X,6)。
会导致实例化错误。你的意思可能是
N#>0
M#>N
。此外,如果在递归目标之前添加目标
R#>=M
,则类似
?-bc(X,2,15)的查询将终止。如果你看帕斯卡三角形,系数要么是
1
(由你的事实覆盖)要么是
R
,那么它出现的最后一行是与
R
在第二个和倒数第二个位置选择
N
。-)@谢谢你!我没有用我最新的“补丁”更新我的帖子,所以谢谢你抓到它们。我在比我展示的代码更晚的代码上运行了我的示例。我感觉到了你,因为我自己也容易发生这样的灾难:-)
| ?- bc(4,X,6).

X = 2 ? ;

no
| ?-
| ?- bc(N, K, 6).

N = 6
K = 1 ? ;

N = 4
K = 2 ? ;

N = 6
K = 5 ? ;

no
| ?- ;