2011-11-12 4 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]. 

을 유발할 수있는 퍼즐 : :이 나는 다음과 같은 오류 얻을 수 있다는 것입니다 실행할 때

[(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 시간 이상 제 코드를보고 있었고 실수를 찾지 못했습니다. 여러분 중 한 분이 이것을보고 올바른 방향으로 다시 되돌릴 시간을 가지기를 바랍니다.

미리 감사드립니다.

+0

오류와 관련된 부분 만 표시하도록 코드를 단순화 할 수 있습니까? – svick

+0

@svick 완료. 나는 관련성이 없어야하는 모든 술어를 제거했다. 내 코드를 약간 변경했기 때문에 나는 또한 나의 질문을 다시 정리했다. – Mental

+1

질문이 아직 열리는 경우 : 나는 너무 많이 자른 것 같아요. 지금 게시 한 코드에서 나는 명백한 것을 볼 수 없습니다. 그러나 block/2 및 rotatePolygon/3 술어가 없기 때문에 직접 추적 할 수도 없습니다. 예를 들어 후자의 경우 출력이 translate/3으로 입력되기 때문에 문제가 될 수 있습니다. – twinterer

답변

1

오류가있는 스택 추적을 가져 오십시오. 일부 Prolog 시스템은 오류가 발생할 때 스택 추적을 표시합니다 : SWI Prolog, SICStus Prolog, Jekejeke Prolog.

Prolog 시스템을 조금 실험해야합니다. 여러 가지 이유 때문에 스택 타스크가 표시되지 않을 수 있습니다. 예를 들어 compile 대신 normal 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을 사용하는 것이 좋습니다.
관련 문제