简体   繁体   English

Prolog与列表

[英]Prolog With Lists

I received this problem and I can't get it done, I don't know what I've done wrong, can someone help me ? 我收到了这个问题,我无法完成,我不知道我做错了什么,有人可以帮我吗?

Write a predicate to add a value v after 1-st, 2-nd, 4-th, 8-th, … element in a list. 写一个谓词,在列表中的第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).

Here's another possibility to define such a predicate. 这是定义这样一个谓词的另一种可能性。 Whenever you are describing lists it is worthwhile to consider using DCGs since they yield easily readable code. 无论何时描述列表,都值得考虑使用DCG,因为它们产生易于阅读的代码。 First let's observe that there's only need for three arguments, namely the list, the element to be inserted and the list with the element already inserted at the desired positions. 首先让我们观察一下,只需要三个参数,即列表,要插入的元素以及已经插入所需位置的元素的列表。 The arguments P and C are only needed for bookkeeping purposes so it's opportune to hide them inside the predicate. 参数PC仅用于簿记目的,因此将它们隐藏在谓词中是恰当的。 And since we're already about to redesign the predicates interface let's also give it a more descriptive name that reflects its relational nature, say list_e_inserted/3: 而且由于我们已经要重新设计谓词接口,所以我们也给它一个更具描述性的名称来反映它的关系性质,比如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

Now let's see the predicate at work: 现在让我们看看谓词在起作用:

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

The predicate also works in the other direction: 谓词也适用于另一个方向:

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

And the most general query also yields the desired solutions: 最通用的查询也会产生所需的解决方案:

?- 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] ;
.
.
.

The main problem is that when a variable in Prolog gets instantiated you can't change the value eg increase the value so you need to use a new variable: 主要问题是当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).

Example: 例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM