2011-11-12 6 views
4

私の「宣言的言語」クラスでは、Tangramパズルを解決するプロローグプログラムを書く必要があります。 パズルは、パズルのポイントの座標のリストによって識別されます。たとえば、puzzle(7,[(0,0),(8,0),(4,4)])は識別子7のパズルで、三角形を表します。ここで`is/2`で十分にインスタンス化されていない引数

は、これを解決するための私の(素朴な)方法です。実行はtangram(Puzzle, Puts)を呼び出して開始します。プログラムはパズルのすべての可能な部分から始まります。私は次にピースを選んで、ポジションと回転を試して、これがパズルの有効なポジションを与えたら、私はパズルを配置します。 (=プログラムの最後に返される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]. 

いくつかの可能なパズル:

ERROR: is/2: Arguments are not sufficiently instantiated 

それをトレースすると、その何とか思えるときは:

[(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)] 

私はこれを実行する問題は、私は次のエラーを取得するということですここでは、コードですTranslateのTXおよびTY値はインスタンス化されません。私は何とかXとYがplacePieces述語でインスタンス化されないと思います。値が残っていなければ、述語は失敗するでしょうか?

私は5時間以上私のコードを見てきたし、私の間違いを見つけるように見えることはできません。 あなたのうちの一人がこれを見て正しい方向に戻す時間がありますように。

ありがとうございます!

+0

エラーに関連する部分のみを表示するようにコードを単純化できますか? – svick

+0

@スウィック完了。私は関連性のない述語をすべて削除しました。私は自分のコードを少し変更したので、私はまた私の質問を再定式化した。 – Mental

+1

質問がまだ開いている場合:あなたはあまりにも多くを切り取ったと思います。あなたが今投稿したコードから、わかりません。しかし、block/2とrotatePolygon/3の述語がないので、私自身もそれをトレースすることはできません。例えば、出力がtranslate/3で入力されているため、後者では問題があります。 – twinterer

答えて

1

エラーが発生したスタックトレースを取得してください。一部のPrologシステムでは、エラーが発生したときにスタックトレースが表示されます。SWI Prolog、SICStus Prolog、Jekejeke Prolog。

あなたのPrologシステムで少し実験する必要があります。いろいろな理由から、スタックタリスが表示されないことがあります。たとえば、コンパイルの代わりに通常のconsultを試してください。または、通常の実行の代わりにデバッグモードを試してみてください。

エラーが発生したときにPrologシステムが自動的にデバッガに入った場合にも、あなたがスタックトレースが表示されない場合があります。しかし、多くの場合、デバッガはスタックトレースを表示するコマンドを提供します。典型的なコマンドは、ゴール(バックトレース)のためのgです。

あなたは問題が発生した場所、あなたがより密接に突き止めることができますスタックトレースを参照してください。

3

あなたは、単に算術演算のためのCLP(FD)制約を使用している場合、このエラーは消えます。単に制約(#=)/2(is)/2を置き換える:

:- use_module(library(clpfd)). 

translate((X, Y), (TX, TY), (RX, RY)):- 
    RX #= X + TX, 
    RY #= Y + TY. 

重要なのは、(#=)/2はすべての方向で使用することができ、また、変数はまだその引数で発生した場合。

その他のコメント:

  1. は、すなわち、X-Yなど
  2. maplist/3はあなたのコードを短縮するのに役立ちますペアを表現するために(-)/2を使用することを検討してください。
関連する問題