我正在SWI-Prolog中实现Checkers,并创建了一个谓词,用于检查给定的移动是否合法:
check_piece_move(white, X/Y, NewX/NewY) :-
AcceptedX1 is X+1, AcceptedX2 is X-1, % white can move to either next or previous column
AcceptedY is Y+1, % and one row upwards
(AcceptedX1 == NewX; AcceptedX2 == NewX), % make sure NewX is acceptable
AcceptedY == NewY. % make sure NewY is acceptable
如果我事先满足所有变量(即给出X / Y和NewX / NewY),这个谓词就能很好地工作。但是,我现在希望它执行相反的操作 - 给定X / Y,它足以使NewX / NewY具有有效的可能性。 我可以改变什么呢? 感谢。
答案 0 :(得分:3)
您可以替换==
(如果术语相同则成功,因此在您的情况下,当NewsX变量时它会失败)并统一=
:
check_piece_move(white, X/Y, NewX/NewY) :-
AcceptedX1 is X+1, AcceptedX2 is X-1,
AcceptedY is Y+1,
(AcceptedX1 = NewX; AcceptedX2 = NewX),
AcceptedY = NewY.
示例:
?- check_piece_move(white,1/2,NewX/NewY).
NewX = 2,
NewY = 3 ;
NewX = 0,
NewY = 3.
更好的方法是使用CLPFD:
:- use_module(library(clpfd)).
check_piece_move(white, X/Y, NewX/NewY) :-
abs(X-NewX) #= 1,
Y+1 #= NewY.
如果提供了X / Y或NewX / NewY中的任何一个,则此方法有效:
?- check_piece_move(white,X/Y,3/1).
X = 4,
Y = 0 ;
X = 2,
Y = 0.
?- check_piece_move(white,3/1,NewX/NewY).
NewX = NewY, NewY = 2 ;
NewX = 4,
NewY = 2.
?- check_piece_move(white,X/Y,3/1).
X = 4,
Y = 0 ;
X = 2,
Y = 0.
?- check_piece_move(white,3/Y,NewX/1).
Y = 0,
NewX = 2 ;
Y = 0,
NewX = 4.
?- check_piece_move(white,X/1,3/NewY).
X = 4,
NewY = 2 ;
X = NewY, NewY = 2.
?- check_piece_move(white,X/Y,NewX/NewY).
NewX+1#=X,
Y+1#=NewY ;
X+1#=NewX,
Y+1#=NewY.