我想在Prolog中用自然数创建后继数字。
nat2s(0, s(0)).
nat2s(NaturalNumber, SNumber) :-
N is NaturalNumber - 1,
nat2s(N, s(SNumber)).
输出应该是这样的:
nat2s(3, X).
X = s(s(s(0))).
实际上它是一个不定式循环。我不知道如何结束循环而不仅仅得到结果。
答案 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