Prolog `is/2中的参数实例化不足`

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

对于我的“声明性语言”类,我们必须编写一个prolog程序来解决七巧板难题。 拼图由拼图点的坐标列表标识。例如,
拼图(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中的输入。