从自然数创建后继数

时间:2017-04-27 17:48:34

标签: prolog successor-arithmetics

我想在Prolog中用自然数创建后继数字。

nat2s(0, s(0)).
nat2s(NaturalNumber, SNumber) :-
            N is NaturalNumber - 1,
            nat2s(N, s(SNumber)).

输出应该是这样的:

nat2s(3, X).
X = s(s(s(0))).

实际上它是一个不定式循环。我不知道如何结束循环而不仅仅得到结果。

1 个答案:

答案 0 :(得分:4)

我建议采用略有不同的方法,即使用库(clpfd)。首先,让我们为谓词选择一个更具声明性的名称。因为在你的帖子中,自然数和s(X)-notation中的数字分别是第一个和第二个参数,所以我们称之为nat_sx / 2。然后可以这样定义谓词:

// the array to be sorted
var list = [10,20,30,40];

// temporary array holds objects with position and sort-value
var mapped = list.map(function(el, i) {
  return { index: i, value: el };
})

// sorting the mapped array
mapped.sort(function(a, b) {
  return b.value - a.value;
});

// you can then remap the sorted mapped array to hold just the indices

这会在您的帖子中产生所需的结果:

:- use_module(library(clpfd)).

nat_sx(0,0).
nat_sx(N,s(X)) :-
   N #> 0,
   N0 #= N-1,
   nat_sx(N0,X).

要了解为什么使用clpfd是有益的,让我们将评论中建议的更正结合到您的代码中并比较两个版本。

   ?- nat_sx(3,X).
X = s(s(s(0))) ? ;
no

以上查询也适用于此版本:

nat2s(0, 0).
nat2s(NaturalNumber, s(SNumber)) :-
   NaturalNumber > 0,
   N is NaturalNumber - 1,
   nat2s(N, SNumber).

然而,能够在另一个方向上使用谓词会很好。那么让我们问一下哪个自然数对应于s(s(0)):

   ?- nat2s(3,S).
S = s(s(s(0))) ? ;
no

实例化错误的原因是/ 2期望右侧有一个无变量表达式:

   ?- nat_sx(N,s(s(0))).
N = 2 ? ;
no
   ?- nat2s(N,s(s(0))).
     ERROR at  clause 2 of user:nat2s/2 !!
     INSTANTIATION ERROR- =:=/2: expected bound value

这也是为什么nat2s / 2的最常见查询在第一个解决方案之后有实例化错误的原因......

   ?- X is 3-1.
X = 2
   ?- 2 is X-1.
     ERROR!!
     INSTANTIATION ERROR- in arithmetic: expected bound value
   ?- 2 is 3-X.
     ERROR!!
     INSTANTIATION ERROR- in arithmetic: expected bound value

...虽然nat_sx / 2一直在生成解决方案:

   ?- nat2s(N,S).
N = S = 0 ? ;
     ERROR at  clause 2 of user:nat2s/2 !!
     INSTANTIATION ERROR- =:=/2: expected bound value