2

我试过这个

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

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

4

2 回答 2

3

为了看到您的程序无法运行,您可以尝试一下:

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

?- fun([1],[]).
true.

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

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

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

最简洁的方法是使用library(lambda)maplist/3中定义的高阶谓词和 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存在于许多 Prolog 中,并且是Prolog prologue 的一部分

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

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

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

你更倾向哪个?

有关 maplist-family 的更多信息:将谓词应用于列表元素的 Prolog 映射过程


如果你想学习 Prolog,首先要坚持纯关系。避免切割。避免副作用,如write. 甚至避免(is)/2。使用和后来的。研究终止和非终止

于 2014-06-18T21:18:19.940 回答
0

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

使用您的代码,这样的事情是正确的:

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蕴涵运算符

于 2014-06-18T21:55:58.770 回答