【问题标题】:Convert peano number s(N) to integer in Prolog在 Prolog 中将 peano 数 s(N) 转换为整数
【发布时间】:2012-01-21 16:06:39
【问题描述】:

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

natural_number(0).
natural_number(s(N)) :- natural_number(N).

规则大致说明:如果N0是自然数,如果不是我们尝试将s/1的内容递归回规则直到内容是0,那么它是一个自然数如果不是那就不是。

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

我已经想到了基本规则:

sToInt(0,0). %sToInt(X,Y) Where X=s(N) and Y=integer of X

这是我的问题:如何将 s(0) 转换为 1 并将 s(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).

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

【问题讨论】:

  • (a) 这是作业吗? (b) 这是一道标准题——你应该可以在任何逻辑编程的教程或教科书中找到它。
  • a)不,我只是想学习 Prolog b)有人会这么想,但我花了大半天的时间试图找到这个问题的答案,但无济于事

标签: prolog clpfd successor-arithmetics


【解决方案1】:

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

:- use_module(library(clpfd)).

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

【讨论】:

    【解决方案2】:

    没问题 nest_right/4 串联 Prolog lambdas!

    :- use_module(library(lambda)).
    :- use_module(library(clpfd)).
    
    :- meta_predicate nest_right(2,?,?,?).
    nest_right(P_2,N,X0,X) :-
       zcompare(Op,N,0),
       ord_nest_right_(Op,P_2,N,X0,X).
    
    :- meta_predicate ord_nest_right_(?,2,?,?,?).
    ord_nest_right_(=,_,_,X,X).
    ord_nest_right_(>,P_2,N,X0,X2) :-
       N0 #= N-1,
       call(P_2,X1,X2),
       nest_right(P_2,N0,X0,X1).
    

    示例查询:

    ?- 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
    

    【讨论】:

      【解决方案3】:

      这是我的:

      实际上更适合 Prolog 的 Peano 数字,以列表的形式。

      为什么要列出?

      • 之间存在同构
        • 长度为 N 的列表仅包含 s 并以空列表结尾
        • 深度为N的递归线性结构,带有函数符号s 以符号 zero 结尾
        • ...所以这些是相同的东西(至少在这种情况下)。
      • 没有特别的理由去坚持 19 世纪的数学家 (即Giuseppe Peano) 被认为是“可以推理的良好结构结构”(源于功能 我想象的应用程序)。
      • 以前做过:有没有人真的用哥德尔化来编码 字符串?不!人们使用字符数组。好想那个。

      我们走吧,中间有个不知道怎么解的小谜语 解决(使用带注释的变量,也许?)

      % ===
      % 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).
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-21
        • 1970-01-01
        • 2011-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-14
        • 1970-01-01
        相关资源
        最近更新 更多