Prolog 使用列表

3

我收到了这个问题,但是无法解决它,不知道哪里出错了,有人能帮我吗?

编写一个谓词,在列表中的第1、2、4、8等位置之后添加值v。

% add(L:list, E:Number, P:Number, C:number, H:List)
% add(i,i,i,i,o)

add([],_,_,_,[]).
add([_|T],E,P,C,[HR|TR]) :-
   P =:= C,
   HR is E,
   C is C+1,
   P is P*2,
   add(T,E,P,C,TR).
add([H|T],E,P,C,[H|TR]) :-
   P =\= C,
   C is C+1,
   add(T,E,P,C,TR).

什么是 E、P、C,以及如何使用它们? - coder
我认为我需要5个来解决这个问题,并且我需要在每个C位置插入E,所以我用P计算位置。 - Oscar Gal
你的意思是在每个P位置上,从我看到的,你尝试了(并且使用C进行计数)? - coder
看一下我的回答,希望能有所帮助... - coder
是的,它有效了,非常感谢 :D - Oscar Gal
显示剩余3条评论
2个回答

6
这里提供了另一种定义这样一个谓词的可能性。每当您描述列表时,考虑使用DCG是值得的,因为它们产生易于阅读的代码。首先让我们观察到只需要三个参数,即列表、要插入的元素和已在所需位置插入元素的列表。参数P和C仅用于簿记目的,因此将它们隐藏在谓词内部是适当的。既然我们已经重新设计了谓词接口,那么让我们也给它一个更具描述性的名称,反映其关系特性,比如说list_e_inserted/3:
list_e_inserted(L,E,I) :-
   phrase(inserted(L,E,1,1),I).  % the DCG inserted//4 describes the list I

inserted([],_E,_P,_C) -->        % if the list L is empty  
   [].                           % the list I is empty as well
inserted([H|T],E,P,P) -->        % if P and C are equal
   {P1 is P*2, C1 is P+1},       % P is doubled and C is increased
   [H,E],                        % H is in the list I, followed by E
   inserted(T,E,P1,C1).          % the same holds for T,E,P1,C1
inserted([H|T],E,P,C) -->        % if P and C are
   {dif(P,C), C1 is C+1},        % different C is increased
   [H],                          % H is in the list I
   inserted(T,E,P,C1).           % the same holds for T,E,P,C1

现在让我们来看一下谓词是如何工作的:
?- list_e_inserted([],10,I).
I = [].

?- list_e_inserted([1],10,I).
I = [1, 10] ;
false.

?- list_e_inserted([1,2],10,I).
I = [1, 10, 2, 10] ;
false.

?- list_e_inserted([1,2,3],10,I).
I = [1, 10, 2, 10, 3] ;
false.

?- list_e_inserted([1,2,3,4],10,I).
I = [1, 10, 2, 10, 3, 4, 10] ;
false.

谓词也可以反向工作:
?- list_e_inserted(L,E,[1,10,2,10,3,4,10,5]).
L = [1, 2, 3, 4, 5],
E = 10 ;
false.

最常见的查询也可以得到所需的解决方案:

?- list_e_inserted(L,E,I).
L = I, I = [] ;
L = [_G23],
I = [_G23, E] ;
L = [_G23, _G35],
I = [_G23, E, _G35, E] ;
L = [_G23, _G35, _G47],
I = [_G23, E, _G35, E, _G47] ;
L = [_G23, _G35, _G47, _G53],
I = [_G23, E, _G35, E, _G47, _G53, E] ;
.
.
.

5
主要问题是,当Prolog中的变量被实例化后,您无法更改其值,例如增加该值,因此您需要使用新变量:
add([],_,_,_,[]).
add([H|T],E,P,C,[H,E|TR]) :-
   P =:= C, 
   C1 is C+1,
   P1 is P*2,
   add(T,E,P1,C1,TR).
add([H|T],E,P,C,[H|TR]) :-
   P =\= C,
   C1 is C+1,
   add(T,E,P,C1,TR).

例子:

?- add([1,2,3,4],10,1,1,L).
L = [1, 10, 2, 10, 3, 4, 10] ;
false.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接