我想在Prolog中迭代一个列表,将生成的结果写入新列表。
使用谓词next_level_segments(List of Start-, Endcoordinates)
我想计算每对Start-和Endcoordinates之间的四个坐标列表,并将这四个列表存储在Ls中。
这意味着当我打电话时,例如
next_level_segments([
[(10,0),(3.3,0)],
[(3.3,0),(0,-5.8)],
[(0,-5.8),(-3.3,0)],
[(-3.3,0),(-10,0)]
])
谓词segments()
应计算其间的四个下一个坐标
这对开始和结束坐标例如[(10,0),(3.3,0)]
。
所以next_level_segments应该迭代起点和终点列表,段应该进行计算和四个列表的结果,每四对坐标应该存储在一个结果列表中。
当我用四个坐标列表调用next_level_segments()
时,计算完成并且当我查看迹线时生成坐标,但是没有正确存储。
据我在轨迹中看到的那样,缺少四个坐标的最后一个列表。
也许有人可能会看一看我的错误。
谢谢
segments([(Sx,Sy),(Ex,Ey)],Ls):-
X2 is Sx+(Ex-Sx)/3,
Y2 is Sy+(Ey-Sy)/3,
R1 is sqrt((X2-Sx)*(X2-Sx)+(Y2-Ey)*(Y2-Ey)),
Phi1 is atan((Y2-Sy)/(X2-Sx)),
X3 is X2 +R1*cos((Phi1-240)*pi/180),
Y3 is Y2 +R1*sin((Phi1+240)*pi/180),
X4 is X2+(X2-Sx),
Y4 is Y2+(Y2-Sy),
Ls=[
[(Sx,Sy),(X2,Y2)],
[(X2,Y2),(X3,Y3)],
[(X3,Y3),(X4,Y4)],
[(X4,Y4),(Ex,Ey)]].
next_level_segments([[(Sx,Sy),(Ex,Ey)]|E],[X|RLs]):-
segments([(Sx,Sy),(Ex,Ey)],X),
next_level_segments(E,RLs).
next_level_segments([],[]).
答案 0 :(得分:4)
您的next_level_segments/2
只需要两个条款(而不是您正在使用的三个条款)。第一个应该是:
next_level_segments([], []).
你现在的第一和第三条都应该去,因为他们没有做任何有用的事情。
递归条款似乎很正常。
像这样纠正,我得到:
?- next_level_segments(
[[(10,0),(3.3,0)],
[(3.3,0),(0,-5.8)],
[(0,-5.8),(-3.3,0)],
[(-3.3,0),(-10,0)]
],
X).
X = [[[(10, 0), (7.766666666666667, 0)], [(7.766666666666667, 0), (6.649999999999999, -1.9341234017852458)], [(6.649999999999999, -1.9341234017852458), (5.533333333333333, 0)], [(5.533333333333333, 0), (3.3, 0)]],
[[(3.3, 0), (2.2, -1.9333333333333333)], [(2.2, -1.9333333333333333), (0.1262841490828066, -5.451200543142186)], [(0.1262841490828066, -5.451200543142186), (1.1000000000000005, -3.8666666666666667)], [(1.1000000000000005, -3.8666666666666667), (0, -5.8)]],
[[(0, -5.8), (-1.0999999999999999, -3.8666666666666663)], [(-1.0999999999999999, -3.8666666666666663), (-3.0456930398351094, -7.310619872034865)], [(-3.0456930398351094, -7.310619872034865), (-2.1999999999999997, -1.9333333333333327)], [(-2.1999999999999997, -1.9333333333333327), (-3.3, 0)]],
[[(-3.3, 0), (-5.533333333333333, 0)], [(-5.533333333333333, 0), (-6.65, -1.9341234017852458)], [(-6.65, -1.9341234017852458), (-7.766666666666667, 0)], [(-7.766666666666667, 0), (-10, 0)]]
].
请记住,像这样的琐碎的列表迭代也可以简单地写成:
maplist(segments, Input, Output)
换句话说,将segments/2
应用于两个列表中的每个对应元素。你必须重新定义你的segments/3
,但要有两个参数而不是三个,例如重写头部:
segments([(Sx,Sy),(Ex,Ey)], Ls)
(将两个第一个参数放在列表中,因为它们在输入列表中)
小评论:Prolog中的一对通常写为X-Y
,而不是(X, Y)
。许多标准库谓词代表"对"作为X-Y
,例如keysort/2
,库(对)等。如果您愿意,还可以为您的对提供一个描述性名称,例如pair(X,Y)
或coordinates(X,Y)
。它并不仅仅是两个元素的关键,而是一个"元组"有三个这样的元素:(X,Y,Z)
实际上是一个嵌套的术语:
?- write_canonical((X,Y,Z)).
','(_,','(_,_))
true.
X-Y-Z
会遇到同样的问题:
?- write_canonical(X-Y-Z).
-(-(_,_),_)
true.
此时您可以再次使用带有描述性名称的字词,例如triple(X, Y, Z)
或coordinates(X, Y, Z)
。