在Prolog中将peano数s(N)转换为整数

在Prolog中将peano数s(N)转换为整数,prolog,clpfd,successor-arithmetics,meta-predicate,Prolog,Clpfd,Successor Arithmetics,Meta Predicate,我在一个教程中遇到了逻辑数的自然数评估,这让我有些头疼: natural_number(0). natural_number(s(N)) :- natural_number(N). 该规则大致说明:如果N是0这是自然数,如果不是,我们尝试将s/1的内容递归发送回该规则,直到内容是0,那么它是自然数如果不是,那么它不是 所以我测试了上面的逻辑实现,我想,如果我想将s(0)表示为1和s(s(0))表示为2,那么这是可行的,但我希望能够将s(0)转换为1 我想到了基本规则: sToInt(0,0).

我在一个教程中遇到了逻辑数的自然数评估,这让我有些头疼:

natural_number(0).
natural_number(s(N)) :- natural_number(N).
该规则大致说明:如果
N
0
这是自然数,如果不是,我们尝试将
s/1
的内容递归发送回该规则,直到内容是
0
,那么它是自然数如果不是,那么它不是

所以我测试了上面的逻辑实现,我想,如果我想将
s(0)
表示为
1
s(s(0))
表示为
2
,那么这是可行的,但我希望能够将
s(0)
转换为
1

我想到了基本规则:

sToInt(0,0). %sToInt(X,Y) Where X=s(N) and Y=integer of X
所以我的问题是:如何将s(0)转换为1,将s(0)转换为2

已得到答复

编辑:我在实现中修改了基本规则,我接受的答案为我指明了方向:

decode(0,0). %was orignally decode(z,0).
decode(s(N),D):- decode(N,E), D is E +1.

encode(0,0). %was orignally encode(0,z).
encode(D,s(N)):- D > 0, E is D-1, encode(E,N).

所以我现在可以随心所欲地使用它了,谢谢大家

这里是另一个使用SWI、YAP或SICStus“双向”工作的解决方案

:- use_module(library(clpfd)).

natsx_int(0, 0).
natsx_int(s(N), I1) :-
   I1 #> 0,
   I2 #= I1 - 1,
   natsx_int(N, I2).

没有问题
右嵌套/4
一起 !

示例查询:

?- nest_right(\X^s(X)^true,3,0,N).
N = s(s(s(0))).                 % succeeds deterministically

?- nest_right(\X^s(X)^true,N,0,s(s(0))).
N = 2 ;                         % succeeds, but leaves behind choicepoint
false.                          % terminates universally
这是我的:

实际上更好地适应Prolog的Peano数字,以列表的形式

为什么要列出清单

  • 两者之间存在同构关系
    • 长度N的列表,仅包含
      s
      ,以空列表结尾
    • 具有函数符号
      s
      N深度的递归线性结构 终止于符号
      0
    • 。。。所以这些都是相同的事情(至少在这种情况下)
  • 没有特别的理由坚持19世纪数学家的观点 (即) 认为“良好的结构与理性”(源于功能 (我想是应用程序)
  • 以前有人这样做过:有人真的使用哥德尔化来编码吗 串?不人们使用字符数组。真想不到
我们走吧,中间有个小谜语我不知道怎么做。 求解(可能使用带注释的变量?)

(a) 这是家庭作业吗?(b) 这是一个标准问题——你应该可以在任何关于逻辑编程的教程或教科书中找到它。a)不,我只是想学习Prolog b)有人会这么想,但我花了大半天的时间试图找到这个问题的答案,但没有用
?- nest_right(\X^s(X)^true,3,0,N).
N = s(s(s(0))).                 % succeeds deterministically

?- nest_right(\X^s(X)^true,N,0,s(s(0))).
N = 2 ;                         % succeeds, but leaves behind choicepoint
false.                          % terminates universally
% ===
% Something to replace (frankly badly named and ugly) "var(X)" and "nonvar(X)"
% ===

ff(X) :- var(X).     % is X a variable referencing a fresh/unbound/uninstantiated term? (is X a "freshvar"?)
bb(X) :- nonvar(X).  % is X a variable referencing an nonfresh/bound/instantiated term? (is X a "boundvar"?)

% ===
% This works if:
% Xn is boundvar and Xp is freshvar: 
%    Map Xn from the domain of integers >=0 to Xp from the domain of lists-of-only-s.
% Xp is boundvar and Xn is freshvar: 
%    Map from the domain of lists-of-only-s to the domain of integers >=0
% Xp is boundvar and Xp is boundvar: 
%    Make sure the two representations are isomorphic to each other (map either
%    way and fail if the mapping gives something else than passed)
% Xp is freshvar and Xp is freshvar: 
%    WE DON'T HANDLE THAT!
%    If you have a freshvar in one domain and the other (these cannot be the same!)
%    you need to set up a constraint between the freshvars (via coroutining?) so that
%    if any of the variables is bound with a value from its respective domain, the
%    other is bound auotmatically with the corresponding value from ITS domain. How to
%    do that? I did it awkwardly using a lookup structure that is passed as 3rd/4th
%    argument, but that's not a solution I would like to see.
% ===

peanoify(Xn,Xp) :-
   (bb(Xn) -> integer(Xn),Xn>=0 ; true),                  % make sure Xn is a good value if bound
   (bb(Xp) -> is_list(Xp),maplist(==(s),Xp) ; true),      % make sure Xp is a good value if bound 
   ((ff(Xn),ff(Xp)) -> throw("Not implemented!") ; true), % TODO
   length(Xp,Xn),maplist(=(s),Xp).

% ===
% Testing is rewarding! 
% Run with: ?- rt(_).
% ===

:- begin_tests(peano).

test(left0,true(Xp=[]))          :- peanoify(0,Xp).
test(right0,true(Xn=0))          :- peanoify(Xn,[]).
test(left1,true(Xp=[s]))         :- peanoify(1,Xp).
test(right1,true(Xn=1))          :- peanoify(Xn,[s]).
test(left2,true(Xp=[s,s]))       :- peanoify(2,Xp).
test(right2,true(Xn=2))          :- peanoify(Xn,[s,s]).
test(left3,true(Xp=[s,s,s]))     :- peanoify(3,Xp).
test(right3,true(Xn=3))          :- peanoify(Xn,[s,s,s]).
test(f1,fail)                    :- peanoify(-1,_).
test(f2,fail)                    :- peanoify(_,[k]).
test(f3,fail)                    :- peanoify(a,_).
test(f4,fail)                    :- peanoify(_,a).
test(f5,fail)                    :- peanoify([s],_).
test(f6,fail)                    :- peanoify(_,1).
test(bi0)                        :- peanoify(0,[]).
test(bi1)                        :- peanoify(1,[s]).
test(bi2)                        :- peanoify(2,[s,s]).

:- end_tests(peano).

rt(peano) :- run_tests(peano).