【问题标题】:Prolog - Increase all the numbers of a list by 1Prolog - 将列表的所有数字增加 1
【发布时间】:2016-12-23 22:10:32
【问题描述】:

我试过了

 fun([],[]).
 fun([A|_],B) :- number(A), B is A +1,!.
 fun([H|T],R) :- fun(T,R).

我知道这是错的,你能帮帮我吗?谢谢

【问题讨论】:

    标签: prolog failure-slice


    【解决方案1】:

    如果您的程序无法运行,您可以尝试一下:

    ?- fun([1],L).
    L = 2.
    
    ?- fun([1],[]).
    true.
    
    ?- fun([X],L).
    L = [].
    

    所以这清楚地表明了非关系行为:在第一个查询中,我们要求L 并得到L = 2 作为答案,但随后我们询问[] 作为答案;系统也接受。显然,您的定义不能是关系。罪魁祸首当然是剪辑。

    除此之外,还有其他方法可以查看问题。只看一条规则就足够了。第一条规则 (fun([A|_],B) :- number(A), B is A +1,!.) 规定第二个参数必须是整数(在某些情况下)。但它应该是一个列表。第二条规则 (fun([H|T],R) :- fun(T,R).) 表示可以跳过任何元素。显然,这不能成为有意义的定义的一部分。

    最简洁的方法是使用高阶谓词maplist/3library(lambda) 中定义的lambda 表达式。这样写,通常不使用中间谓词。

    fun(Xs, Ys) :-
       maplist(\X^Y^(Y is X+1), Xs, Ys).
    

    下一个版本避免使用 lambda,而是使用具体定义:

    msucc(X, Y) :-
       Y is X+1.
    
    fun(Xs, Ys) :-
       maplist(msucc, Xs, Ys).
    

    事实上,有一个预定义的谓词succ/2,它出现在许多Prologs中,是part of the Prolog prologue

    fun(Xs, Ys) :-
       maplist(msucc, Xs, Ys).
    

    定义它的最“简单”的方式是直接使用谓词定义:

    fun([], []).
    fun([X|Xs], [Y|Ys]) :-
       Y is X+1,
       fun(Xs, Ys).
    

    你更喜欢哪一个?

    有关地图列表系列的更多信息:Prolog map procedure that applies predicate to list elements


    如果你想学习 Prolog,首先要坚持纯关系。避免切割。避免像write 这样的副作用。甚至避免(is)/2。使用 和更高版本的。研究终止和不终止

    【讨论】:

      【解决方案2】:

      问题是你不一致,你没有完成递归。

      你的代码是这样的:

      fun([a,b,c],X) .
      

      会导致 X 的值为 [],但是

      fun([a,1,b],X) .
      

      将导致 X 的值为 2

      如果您想找到列表中的第一个数字并将其加一,则可以这样做:

      fun([X|Xs],Y) :- number(X) , ! , Y is X+1 .
      fun([_|Xs],Y) :- fun(Xs,Y) .
      

      如果您想增加列表中的每个数字,请尝试以下操作:

      fun( []    , []      ) .  % if the source list is exhausted, we're done.
      fun( [X|Xs] , [Y|Ys] ) :- % otherwise,
        number(X) ,             % - if X is a number,
        Y is A+1                % - we increment it to get Y
        fun( Xs , Ys ) .        % - and recurse down on the tails of the respective lists
      fun( [X|Xs] , [X|Ys] ) :- % otherwise, add X to the result list
        \+ number(X) ,          % - assuming X is not a number,
        fun(Xs,Ys) .            % - and recurse down.
      

      你不应该认为这可以更简洁地表述为

      fun( [] , [] ) :-
      fun( [X|Xs] , [Y|Ys] ) :-
        increment(X,Y) ,
        fun( Xs , Ys )
        .
      
      increment(X,Y) :- number(X) , ! , Y is X+1 .
      increment(X,X) .
      

      或者,更简洁

      fun( [] , [] ) .
      fun( [X|Xs] , [Y|Ys] ) :-
        ( number(X) -> Y is X+1 ; Y = X ) ,
        fun(Xs,Ys).
      

      A -> B ; C 构造是implication operator

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-05
        相关资源
        最近更新 更多