For my Declarative Languages โโclass, we have to write a prologue program that solves the mysteries of Tangram. The puzzle is identified by the list of coordinates of the puzzle points. For example, puzzle(7,[(0,0),(8,0),(4,4)]) is a puzzle with identifier 7 and is a triangle.
Here is my (naive) way to solve this. Execution begins with a call to tangram(Puzzle, Puts) . The program begins with all possible pieces of the puzzle. Then I select a piece, try the position and rotation, and if this gives the correct position for the puzzle, I place the puzzle. (= put the block on the Puts list, which will be returned at the end of the program.) I will return to these possibilities. Here is the code:
%Harm De Weirdt %3e Bachelor Informatica %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% MAIN PROGRAM %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %All possible rotations of a piece. angle(0). angle(90). angle(180). angle(270). %Puzzle is a list of the coordinates of the corners of the puzzle to be solved. %Puts is a list of 7 elements indicating how each piece should be placed in order to solve the puzzle. tangram(Puzzle, Puts):- findall(block(BlockId, PointList), block(BlockId, PointList), PossiblePieces), placePieces(PossiblePieces, Puts, Puzzle). %placePieces(Pieces, Puts) %Place all the puzzle pieces from Pieces on the puzzle. %Puts is a list containing the position of all the pieces. placePieces([], _,_). placePieces([block(BlockId, PointList)|OtherPieces], Puts, Puzzle):- between(0,8,X), between(0,6,Y), angle(Angle), allowedPosition(PointList, (X,Y), Angle, Puzzle, Puts), append(Puts, [put(BlockId, ((X,Y), Angle))], NewPuts), placePieces(OtherPieces, NewPuts, Puzzle), write(Puts). allowedPosition(Block, (X,Y), Angle, Puzzle, Puts):- rotatePolygon(Block, Angle, RotatedPolygon), translatePolygon(RotatedPolygon, (X,Y), TranslatedPolygon), insideFigure(TranslatedPolygon, Puzzle), noOverlap(TranslatedPolygon, Puts). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXTRA PREDICATES %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %translate(Point, TranslationVector, TranslatedPoint) %TranslatedPoint is the result of Translating Point with TranslationVector translate((X, Y), (TX, TY), (RX, RY)):- RX is X + TX, RY is Y + TY. %translatePolygon(Polygon, TranslationVector, TranslatedPolygon) %Translates a Polygon, defined by a list of its Points, by a given TranslationVector, %resulting in the TranslatedPolygon translatePolygon([], _Vector, []). translatePolygon([(X,Y)|Rest], (TX, TY), TranslatedPolygon):- translatePolygon(Rest, (TX, TY), PartiallyTranslatedPolygon), translate((X, Y), (TX, TY), (NewX, NewY)), TranslatedPolygon = [(NewX, NewY)| PartiallyTranslatedPolygon].
Some possible puzzles:
[(0,0),(4,0),(4,4),(0,4)] [(3,0),(5,2),(5,4),(4,5),(2,5),(0,3)] [(0,0),(6,0),(7,1),(7,3),(3,3)]
The problem when I run this is that I get the following error:
ERROR: is/2: Arguments are not sufficiently instantiated
When tracing, it seems that somehow the TX and TY values โโare not created in the translation. Track backwards I think that X and Y are somehow not created at the placePieces predicate place. If there were no values โโleft, the predicate simply failed, right?
I have been looking at my code for more than 5 hours and it seems I cannot find my error. I hope one of you has time to look at it and get me back in the right direction.
Thanks in advance!