Prolog:下一个三角形数字

时间:2013-11-21 18:16:57

标签: prolog

我正在做一个需要定义关系nexttri(X,Y)的赋值,使得Y是大于X的最小三角数。

例如

?- nexttri(1,3).
true.
?- nexttri(6,Y).
Y = 10.

我不知道该怎么做。

3 个答案:

答案 0 :(得分:1)

此解决方案类似于CapelliC,但会接受三角数最小不等于给定数的情况,从而满足OP的要求定义关系nexttri(X,Y),使得Y是最小三角形数字大于X

nexttri(X, TriNum) :-
    nexttri(X, 1, 1, TriNum).
nexttri(X, TriCnt, TriInc, TriNum) :-
    NextCnt is TriCnt + 1,
    NextInc is TriInc + NextCnt,
    (   X < TriInc
    ->  TriNum = TriInc
    ;   nexttri(X, NextCnt, NextInc, TriNum)
    ).

?- nexttri(1,1).
false.
?- nexttri(1,3).
true.
?- nexttri(1,4).
false.
?- nexttri(1,6).
false.
?- nexttri(6,Y).
Y = 10.
?- nexttri(9,Y).
Y = 10.
?- nexttri(10,Y).
Y = 15.

答案 1 :(得分:0)

你真的试过什么吗?对于SO来说,显示你的代码几乎是 de rigeur

假设这是你所说的“三角数”:http://en.wikipedia.org/wiki/Triangular_number

让我们首先定义一个谓词,它将[理论上]生成一个永无止境的三角数流。由于prolog变量是“一次写入”和本地变量,因此需要使用累加器。因此,一个常见的prolog习惯用法是像这样的公共接口谓词的概念,它只是调用私有工作者谓词。像这样:

triangular_number(X) :- triangular_number(1,X) .

我们使用1对序列进行种子处理。然后,工作者谓词计算等边三角形的三角形数字,其长度为 n ,并将该值与X统一。在回溯时,它会递增< em> n 并递归。像这样:

triangular_number(P,X) :- P > 0 , sum(P,X) .
triangular_number(P,X) :- P > 0 , P1 is P+1 , triangular_number(P1,X) .

当我们回溯到triangular_number / 1时,X与下一个三角数重复统一,给我们永无止境的序列。

这里的worker谓词,triangular_number / 3调用它自己的worker谓词sum / 2,它计算N + N-1 + N-2系列......直到N递减到零,所以sum(3,X) )产生3 + 2 + 1。像这样:

sum(N,X) :- sum(N,0,X) .

sum(0,X,X).
sum(N,T,X) :-
  N > 0 ,
  N1 is N-1 ,
  T1 is T+N ,
  sum(N1,T1,X)
  .

你是否开始注意到这里的模式?

一旦我们可以生成三角形数字,找出大于特定值的下一个三角形数字很容易:

next_triangular_number(N,X) :-
  triangular_number(X) ,
  X > N ,
  ! .

调用triangular_number / 1获取第一个三角形数字(1),将其与指定的边界(N)进行比较,然后成功或失败,仅回溯到triangualar_number / 1,再次使用下一个三角形数字成功。< / p>

轻松!让prolog的推理引擎完成工作。

您是否希望这是确定性的(通过使用剪切!)取决于您的问题定义。这应该只有一个答案,还是应该继续寻找回溯的解决方案?

答案 2 :(得分:0)

这是一个基于T(0) = 0T(n) = T(n-1)+n的事实的解决方案,在我们的案例中n未知。只需计算序列,传递假设的T(n-1):

tri_succ(P, T) :- tri_succ(0, 0, P, T).
tri_succ(N, Tn, L, S) :-
    N1 is N+1,
    Ts is Tn+N1,
    (   L = Tn
    ->  S = Ts
    ;   L > Tn
    ->  tri_succ(N1, Ts, L, S)
    ).

试验:

25 ?- tri_succ(1,T).
T = 3.

26 ?- tri_succ(6,T).
T = 10.

27 ?- tri_succ(7,T).
false.