[英]Prolog With Lists
我收到了这个问题,我无法完成,我不知道我做错了什么,有人可以帮我吗?
写一个谓词,在列表中的第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).
这是定义这样一个谓词的另一种可能性。 无论何时描述列表,都值得考虑使用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] ;
.
.
.
主要问题是当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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.