Prolog 序言。在自然项的数量中打断整数

Prolog 序言。在自然项的数量中打断整数,prolog,visual-prolog,Prolog,Visual Prolog,我的任务是:在自然项的数量中找到正整数的分区数。 例如:N=5。答案是7,因为5:{1,1,1,1},{2,1,1},{2,2,1},{3,1,1},{3,2},{4,1},{5} 我在JS上写了一个解决方案: function pcount(number, limit) { if (limit === 0) { if (number === 0) { return 1; } return 0; } if (limit <= number) { return

我的任务是:在自然项的数量中找到正整数的分区数。 例如:N=5。答案是7,因为5:{1,1,1,1},{2,1,1},{2,2,1},{3,1,1},{3,2},{4,1},{5}

我在JS上写了一个解决方案:

function pcount(number, limit) { 
 if (limit === 0) {
  if (number === 0) {
   return 1;
  }
  return 0;
 }

 if (limit <= number) {
  return pcount(number, limit - 1) + pcount(number - limit, limit);
 }

 return pcount(number, number);
}

但它不起作用。此谓词出错:
检查(数字、限制、结果)
。如何组合两个谓词调用的结果:
check(Number,Limit-1)+check(Number Limit,Limit)

您所拥有的非常接近正确,但需要更多的约束。现有子句正在递归为负值
Limit
。这里有一个小的更新可以解决这个问题,还有一些小的调整:

check(0, 0, 1).
check(N, 0, 0) :-
    N > 0.                   % Added constraint N > 0
                             %    avoids overlap with first clause
check(Number, Limit, Result):-
    Limit > 0,               % Added constraint Limit > 0 avoids overlap
                             %    with first clause and negative values
    Limit <= Number, !,
    NN = Limit - 1,
    RR = Number - Limit,
    check(Number, NN, Result1),
    check(RR, Limit, Result2),
    Result = Result1 + Result2.
check(Number, Limit, Result) :-    % Case were Limit > Number as in your
    Limit > Number,                %    original non-Prolog code
    check(Number, Number, Result).

check(A, B):-
    check(A, B, X),
    write(X).
检查(0,0,1)。
检查(N,0,0):-
N>0.%添加了约束N>0
%避免与第一个子句重叠
检查(数量、限制、结果):-
限制>0%,添加的约束限制>0可避免重叠
%带第一子句和负值
限制数量,如您的
限制>数量,%original非Prolog代码
检查(编号、编号、结果)。
检查(A,B):-
检查(A、B、X),
写(X)。

Prolog没有函数,只有谓词。谓词成功或失败,不返回值。但是您可以用一个结果(例如,
pcount(5,5,result)
)实例化一个变量参数。我不知道你为什么担心这个。这是一种根本不同的语言。至于只映射if-then-else,您可能会感兴趣。我一直忘了Turbo/visualprolog允许
在解决这个问题之前,您可能需要先阅读一个基本的prolog教程。像,
pcount(Number,Limit-1)+pcount(Number Limit,Limit)
这样的表达式根本不会做你认为它会做的事。ty,但是
Goal1->Goal2;Goal3
语句在visual prolog中不起作用。不幸的是,visual prolog与标准prolog有很大的不同。不过,您所更新的内容非常接近正确。您的第二个子句,
check(\u0,Result)
需要确保数字大于0,以避免与第一个案例重叠。您需要一个子句来处理
Number>Limit
。这个谓词的错误到底是什么。。。?仅供参考,您可以编写,
检查(0,0,1)。
而不是
检查(0,0,R):-R=1。
(我认为Visual Prolog可以让您这样做-这是标准的Prolog。)哇,天哪!它起作用了。我完全忘记了最后一个条件
pcount(number,number)
。谢谢您的帮助、建议和耐心。@helterheed我很高兴这对您有用。:)你能接受它作为一个答案吗?哦,对不起,我是stackoverflow的新手,忘了它。我做了标记
check(0, 0, 1).
check(N, 0, 0) :-
    N > 0.                   % Added constraint N > 0
                             %    avoids overlap with first clause
check(Number, Limit, Result):-
    Limit > 0,               % Added constraint Limit > 0 avoids overlap
                             %    with first clause and negative values
    Limit <= Number, !,
    NN = Limit - 1,
    RR = Number - Limit,
    check(Number, NN, Result1),
    check(RR, Limit, Result2),
    Result = Result1 + Result2.
check(Number, Limit, Result) :-    % Case were Limit > Number as in your
    Limit > Number,                %    original non-Prolog code
    check(Number, Number, Result).

check(A, B):-
    check(A, B, X),
    write(X).