Program description
- Aim of the program
My program is meant to calculate locations of shapes in a 20X15 sized plane. I have a list of shapes carrying the shape type, its id, its radius or height, and its prospective [X,Y] location on the plane. I have a different list of binary operations carrying only the shape type, its id, and its location relationship with another shape. With this information in the operations list, I should compute the [X,Y] locations of the shapes: Below is a description of the two lists:
List of shapes
I have a list of shapes: each shape is a list of the form:
[[shape, id],height/radius, [X,Y]]
A list of such shapes would look something like the below when it is printed out by Prolog:
[[[diamond,1],4,[_7948,_7954]],[[circle,3],6,[_7894,_7900]],[[square,1],4,[_7840,_7846]],[[circle,1],5,[_7786,_7792]]|_7800]
List of operations
A list of operations that should be carried out on the shapes each operation is of the form:
[[[circle,1],below,[square,1]]]
This means that circle 1 should appear below square 1 on the X,Y plane
Such a list when printed out by prolog would look something like the following:
[[[circle,1],below,[square,1]]|_8016]
- The program
So I have computeShapeLocations/2
. Its first argument is a list of operations and the second list is a list of shapes. It recursively goes over the list of operations getting the shape ids on both sides of the operation. eg circle 1 - below - sqaure 1
and sends the two shapes to the correct function to calculate the locations using CLPFD. For two shapes with a relative positioning of 'below' I use computeShapesBelow/2
which takes two shapes each of the form [[shape, id],height/radius, [X,Y]]
.
Steps in ComputeShapeLocations/2:
1. Get an operation of the form [[[circle,1],below,[square,1]]] from the list of operations
2. Fetch first id (circle 1), then type of relationship (below) then second id (square 1).
3. Fetch the shapes from the shapes list (ShapesOut)
4. Send the shapes to computeShapesBelow/2
. This just uses clpfd to compare radius or height and the dimensions of my X,Y plane.
:- 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.
The problem:
In computeShapeLocations/2
my lookup is just bizarre( see step three above in steps of computeShapeLocations/2
). I use member(ShapeId, ListOFshapesList) to fetch shapes from listofshapes given their ids [shape,id]. I then print out the results( writeln(Shape1), writeln(Shape2)
)and the image below shows just how the behavior is wrong. For the first shape (circle,1), the result is good and computeShapesBelow/2
even comes up with a proper limit of its X,Y location (6..14 and 6..9). For the second shape (Shape2 or square 1). It does not behave as expected and the clpfd limits result in lower infinities.
The reason is because this second search of [square,1] ignores an entry of [[square, 1], 4, [_2166, _2172]]
which is in the list and instead somehow adds an extra [[square, 1], _2250, [_2262|...]]
which it then uses to mess up my results.
[[Subject|Tail]|_]
. That's why you're seeing_4276
, etc. What is_
really supposed to be? – lurkerappend([], ShapesIn, ShapesOut)
can be simplified to this unification:ShapesIn = ShapesOut
. Appending a list to an empty list yields the same list. – lurker