Prolog `is/2中的参数实例化不足`
对于我的“声明性语言”类,我们必须编写一个prolog程序来解决七巧板难题。 拼图由拼图点的坐标列表标识。例如,Prolog `is/2中的参数实例化不足`,prolog,clpfd,instantiation-error,meta-predicate,Prolog,Clpfd,Instantiation Error,Meta Predicate,对于我的“声明性语言”类,我们必须编写一个prolog程序来解决七巧板难题。 拼图由拼图点的坐标列表标识。例如,拼图(7,[(0,0)、(8,0)、(4,4)])是一个标识符为7的拼图,表示一个三角形 这是我(天真的)解决这个问题的方法。执行从调用七巧板开始。程序从拼图的所有可能的部分开始。然后我选择一块,尝试一个位置和一个旋转,如果这为拼图提供了一个有效的位置,我放置拼图。(=将块放在Puts列表中,该列表将在程序结束时返回。)我回顾了所有这些可能性。代码如下: %Harm De We
拼图(7,[(0,0)、(8,0)、(4,4)])
是一个标识符为7的拼图,表示一个三角形
这是我(天真的)解决这个问题的方法。执行从调用七巧板开始。程序从拼图的所有可能的部分开始。然后我选择一块,尝试一个位置和一个旋转,如果这为拼图提供了一个有效的位置,我放置拼图。(=将块放在Puts列表中,该列表将在程序结束时返回。)我回顾了所有这些可能性。代码如下:
%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].
一些可能的困惑:
[(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)]
运行此操作时出现的问题是,出现以下错误:
ERROR: is/2: Arguments are not sufficiently instantiated
跟踪时,Translate中的TX和TY值似乎没有实例化。追溯过去,我认为不知何故X和Y没有在placePieces谓词中实例化。如果没有剩下的值,谓词就会失败,对吗
我已经看了5个多小时的代码,似乎找不到我的错误。
希望你们中的一位有时间来审视这一点,让我回到正确的方向
提前谢谢 尝试获取带有错误的堆栈跟踪。某些Prolog系统在发生错误时显示堆栈跟踪:SWI Prolog、SICStus Prolog、Jekejeke Prolog 您必须对Prolog系统进行一点试验。由于各种原因,可能不会显示堆栈tarce。例如,尝试正常的查询而不是编译。或者尝试打开调试模式,而不是正常执行 此外,如果Prolog系统在发生错误时自动进入调试器,则可能看不到堆栈跟踪。但调试器通常会提供一个命令来显示堆栈跟踪。典型的命令是:g for goals(backtrace)
当您看到堆栈跟踪时,可以更精确地确定问题发生的位置 如果简单地将CLP(FD)约束用于算术,则此错误将消失。只需将
(is)/2
替换为约束(#=)/2
:
:- use_module(library(clpfd)).
translate((X, Y), (TX, TY), (RX, RY)):-
RX #= X + TX,
RY #= Y + TY.
重要的是,(#=)/2
可以在所有方向上使用,如果变量仍然出现在其参数中也可以
其他意见:
(-)/2
表示对,即X-Y
等你能简化代码,只显示与错误相关的部分吗?@svick Done。我删除了所有不相关的谓词。因为我对代码做了一些修改,所以我也重新制定了我的问题。如果问题仍然存在:我认为你删掉了太多。从你现在发布的代码中,我看不出任何明显的错误。但是我自己也无法尝试跟踪它,因为block/2和rotatePolygon/3谓词缺失。例如,它可能是后者的一个问题,因为它的输出是translate/3中的输入。