程序描述
- 程序目的
我的程序旨在计算20X15大小平面上形状的位置。我有一个形状列表,其中包含形状类型、其ID、其半径或高度以及其在平面上的潜在[X,Y]位置。我有一个不同的二进制操作列表,仅包含形状类型、其ID以及其与另一个形状的位置关系。根据操作列表中的信息,我应该计算出形状的[X,Y]位置。以下是这两个列表的描述:
形状列表
我有一个形状列表:每个形状都是以下形式的列表:
[[形状,ID],高度/半径,[X,Y]]
当Prolog打印出这样的一组形状时,其列表可能如下所示:
[[[diamond,1],4,[_7948,_7954]],[[circle,3],6,[_7894,_7900]],[[square,1],4,[_7840,_7846]],[[circle,1],5,[_7786,_7792]]|_7800]
操作列表
应对形状执行的操作列表,每个操作的格式如下:
[[[circle,1],below,[square,1]]]
这意味着圆形1应该出现在X,Y平面上方形1的下方。
当Prolog打印出这样的列表时,它看起来像以下内容:
[[[circle,1],below,[square,1]]|_8016]
- 程序
我有一个名为 computeShapeLocations/2
的程序。它的第一个参数是一个操作列表,第二个参数是一个形状列表。它递归地遍历操作列表,获取操作两侧的形状 ID。例如 circle 1 - below - sqaure 1
,并将这两个形状发送到正确的函数中,使用 CLPFD 计算位置。对于相对定位为“below”的两个形状,我使用 computeShapesBelow/2
,它接受两个形状,每个形状的形式为 [[shape, id],height/radius, [X,Y]]
。
computeShapeLocations/2
中的步骤:
1. 从操作列表中获取形如 [[[circle,1],below,[square,1]]] 的操作
2. 获取第一个 ID(circle 1),然后是关系类型(below),最后是第二个 ID(square 1)
3. 从形状列表(ShapesOut)中获取形状
4. 将形状发送到 computeShapesBelow/2
。这只是使用 CLPFD 比较半径或高度以及我的 X、Y 平面的尺寸。
:- use_module(library(clpfd)).
computeShapeLocations([],_ShapesOut).
computeShapeLocations([Operation|Rest],ShapesOut) :- writeln(ShapesOut),
writeln([Operation|Rest]),
nth0(0,Operation,Subject1),
nth0(1,Operation,below),
nth0(2,Operation,Subject2),
Shape1 = [Subject1,H,Loc],
Shape2 = [Subject2,H2,Loc2],
member(Shape1,ShapesOut),
member(Shape2,ShapesOut),
writeln(Shape1),
writeln(Shape2),
writeln(Subject1),
writeln(Subject2),
computeShapeBelow(Shape1,Shape2),
computeShapeLocations(Rest,ShapesOut).
computeShapeBelow(Shape1,Shape2) :- nth0(2,Shape1,Location1),
nth0(2,Shape2,Location2),
writeln(Shape1),
writeln(Shape2),
nth0(1,Shape1,Dim1),
nth0(1,Shape2,Dim2),
nth0(0,Location1,Xcord1),
nth0(0,Location2,Xcord2),
nth0(1,Location1,Ycord1),
nth0(1,Location2,Ycord2),
Ycord1 #> Dim1, Ycord1 #< 15-Dim1,
Xcord1 #> Dim1, Xcord1 #< 20-Dim1,
Ycord2 #> Dim2, Ycord2 #< 15-Dim2,
Xcord2 #> Dim2, Xcord2 #< 20-Dim2,
Ycord2 #> Ycord1+Dim2+Dim1.
问题:
在computeShapeLocations/2
中,我的查找方式非常奇怪(请参见上述步骤三中的computeShapeLocations/2
步骤)。我使用member(ShapeId, ListOFshapesList)
根据id从listofshapes中获取形状[shape,id]。然后我打印出结果(writeln(Shape1), writeln(Shape2)
),下面的图像显示了行为错误的情况。对于第一个形状(圆形,1),结果是好的,computeShapesBelow/2
甚至能够得出其X、Y位置的正确限制(6..14和6..9)。对于第二个形状(Shape2或正方形1),它的行为不符合预期,clpfd限制导致较低的无穷大。由于第二次搜索[square,1]忽略了列表中的一个条目
[[square, 1], 4, [_2166, _2172]]
,而是不知何故添加了额外的[[square, 1], _2250, [_2262|...]]
,这导致了我的结果混乱。![在此输入图片描述](https://istack.dev59.com/YP416.webp)
nth0/3
而对你进行惩罚。 - Daniel Lyons