그리드에서 가능한 모든 경로를 찾기 위해이 프롤로그 프로그램을 작성했습니다.
travel([X,Y],[X,Y1]) :- Y1 is Y+1.
travel([X,Y],[X,Y0]) :- Y0 is Y-1.
travel([X,Y],[X1,Y]) :- X1 is X+1.
move([X,Y],n,[X,Y1]) :- travel([X,Y],[X,Y1]).
move([X,Y],s,[X,Y0]) :- travel([X,Y],[X,Y0]).
move([X,Y],e,[X1,Y]) :- travel([X,Y],[X1,Y]).
safe([Xn,Yn],[Xg,Yg]) :-
Xg >= Xn,
Xn >= 0,
Yg >= Yn,
Yn >= 0. %next state should be whit-in grid
%% solve([X,Y],[TargetX,TargetY],[Xg,Yg],[FirstMove|OtherMoves])
solve([X,Y],[X,Y],_,[]).
solve([X,Y],[Xt,Yt],[Xg,Yg],[Fm|Om]) :-
move([X,Y],Fm,[Xn,Yn]),
safe([Xn,Yn],[Xg,Yg]),
solve([Xn,Yn],[Xt,Yt],[Xg,Yg],Om).
의 경우 solve
[X, Y]는 현재 위치입니다. 그래서 내 종료 상태는 현재 위치가 목표 위치와 같을 때입니다. 그러나 실행하면 메모리 부족 오류가 발생했습니다. 내가 뭘 잘못했는지 알아? 도움을 주시면 감사하겠습니다!
?- solve([1,2],[4,2],[3,4],P).
ERROR: Stack limit (1.0Gb) exceeded
ERROR: Stack sizes: local: 0.5Gb, global: 0.4Gb, trail: 29.0Mb
ERROR: Stack depth: 951,746, last-call: 0%, Choice points: 1,903,475
ERROR: Possible non-terminating recursion:
ERROR: [951,746] user:solve([length:2], [length:2], [length:2], _114212638)
ERROR: [951,745] user:solve([length:2], [length:2], [length:2], [length:1|_114212704])
?- length(P,4),solve([1,2],[4,2],[3,4],P).
false.
?- length(P,5),solve([1,2],[4,2],[3,4],P).
false.
프로그램은 북쪽과 남쪽의 움직임 사이를 무한 반복합니다. 에서 남쪽 절을 제거하려고 move
하고 travel
그것은 작동합니다.
이것이 어떻게 발생하는지 디버깅하려면 trace
재귀 호출을 사용 하여 확인하십시오 solve
.
Exit: (15) move([1, 3], n, [1, 4]) ?
Call: (15) safe([1, 4], [4, 4]) ? s
Exit: (15) safe([1, 4], [4, 4]) ?
Call: (15) solve([1, 4], [3, 4], [4, 4], _3490) ?
Call: (16) move([1, 4], _3804, [_3822, _3828]) ? s
Exit: (16) move([1, 4], n, [1, 5]) ?
Call: (16) safe([1, 5], [4, 4]) ? s
Fail: (16) safe([1, 5], [4, 4]) ?
Redo: (16) move([1, 4], _3804, [_3822, _3828]) ? s
Exit: (16) move([1, 4], s, [1, 3]) ?
Call: (16) safe([1, 3], [4, 4]) ? s
Exit: (16) safe([1, 3], [4, 4]) ?
Call: (16) solve([1, 3], [3, 4], [4, 4], _3806) ?
Call: (17) move([1, 3], _4326, [_4344, _4350]) ? s
Exit: (17) move([1, 3], n, [1, 4]) ?
Call: (17) safe([1, 4], [4, 4]) ? s
Exit: (17) safe([1, 4], [4, 4]) ?
Call: (17) solve([1, 4], [3, 4], [4, 4], _4328) ?
Call: (18) move([1, 4], _4642, [_4660, _4666]) ? s
Exit: (18) move([1, 4], n, [1, 5]) ?
Call: (18) safe([1, 5], [4, 4]) ? s
Fail: (18) safe([1, 5], [4, 4]) ?
또한에서 변수 이름과 일치하는 패턴으로 보이지만 move :- travel
작동하지 않습니다. move(P1, n, P2)
첫 번째 절만이 아닌 북쪽과 남쪽 절을 시도 move([2, 2], s, X)
합니다 (첫 번째 해결책이 북쪽 운동임을 확인하십시오). 이것은 작동하지만 south 절을 사용하면 무한 재귀를 갖게됩니다.
move([X,Y], n, [X,Y1]) :- Y1 is Y+1.
move([X,Y], s, [X,Y1]) :- Y1 is Y-1.
move([X,Y], e, [X1,Y]) :- X1 is X+1.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다