List Prolog-更改列表的元素
完成一本书中的初学者练习,我想取一个列表List Prolog-更改列表的元素,list,prolog,List,Prolog,完成一本书中的初学者练习,我想取一个列表X并更改其元素,以便对于一些[H | X]新列表Y将头元素设置为(H-1,H+1) 比如: X=[1,20,300] --> Y=[(0,2),(19,21),(299,301)] 到目前为止,我添加的是第一个元素,但随后返回一些奇怪的“\u编号”。到目前为止,我所拥有的: switch([], []). switch([H|X], Y) :- H1 is H-1, H2 is H+1, append([(H1,H2)], [],
X
并更改其元素,以便对于一些[H | X]
新列表Y
将头元素设置为(H-1,H+1)
比如:
X=[1,20,300] --> Y=[(0,2),(19,21),(299,301)]
到目前为止,我添加的是第一个元素,但随后返回一些奇怪的“\u编号”。到目前为止,我所拥有的:
switch([], []).
switch([H|X], Y) :-
H1 is H-1,
H2 is H+1,
append([(H1,H2)], [], Y).
这里有两个问题:
append
ing[(H1,H2)]
和[]
为我们提供了一个我们可以提前知道的结果:Y
也将是[(H1,H2)]
李>
在本例中,您不会对尾部X
执行任何操作,因此只处理第一个元素,然后丢弃该元素
因此,谓词将只处理第一个元素,并使用该元组创建一个列表,如:
?- switch([1,2,3], Y).
Y = [(0, 2)].
事实上,这里根本不需要append/3
:我们有两个参数,如果前者是非空的,那么后者也是非空的,反之亦然。因此,我们的递归子句具有以下形状:
switch([], []).
switch([H|T], [(H1, H2)|TT]) :-
%% ...
因此,我们需要指定H
和H1
和H2
之间的关系;和T
和TT
(“元组列表”的其余元素)。至于H
,这已经实现了H1是H-1
,H2是
H+1。对于
T和
TT,我们只需要继续处理,所以我们使用
T和
TT`进行递归调用:
switch([], []).
switch([H|T], [(H1, H2)|TT]) :-
H1 is H-1,
H2 is H+1,
switch(T, TT).
使用
在这里,我们只能在一个方向上进行查询:如果我们用第二个参数统一一个2元组列表,那么Prolog就不能派生第一个列表中的元素。但是,我们可以定义这些元素之间的约束,因此,我们可以从几个方向进行查询:
:- use_module(library(clpfd)).
switch([], []).
switch([H|T], [(H1, H2)|TT]) :-
H1 #= H-1,
H2 #= H+1,
switch(T, TT).
合作
我们正在解决的任务是典型的“映射任务”。因此,我们可以“废弃我们的样板”,并使用:
:-使用_模块(库(clpfd))。
开关组(H,(H1,H2)):-
H1#=H-1,
H2#=H+1。
开关(L1、L2):-
地图列表(切换元组,L1,L2)。
非常感谢您给出了这个详细的答案。我一直在与列表操作作斗争,你的解释似乎很好!
?- switch(L, [(1, A), (3, 5), (C, 7)]).
L = [2, 4, 6],
A = 3,
C = 5.
:- use_module(library(clpfd)).
switch_tuple(H, (H1, H2)) :-
H1 #= H-1,
H2 #= H+1.
switch(L1, L2) :-
maplist(switch_tuple, L1, L2).