148 Lp trình lägich trong Prolog
8
7
6
5
4
3
2
1
1
2
3
4
5
6
7
8
Hình II.7. Mt li gii ca bài toán tám quân hu,
biu din bi danh sách [ 1/4, 2/2, 3/7, 4/3, 5/6, 6/8, 7/5, 8/1
] .
/ ây, phép toán / không phi phép chia, ch" cách t( hp hai to 
ca mt ô bàn c. Hình 5.6 trên ây mt li gii khác ca bài toán tám quân
hu c biu din di dng mt danh sách nh sau :
[ 1/4, 2/2, 3/7, 4/3, 5/6, 6/8, 7/5, 8/1 ]
T' cách biu din danh sách, ta cn tìm li gii có dng :
[ X1/Y1, X2/Y2, X3/Y3, ... , X8/Y8 ]
Ta cn m c gtr ca các bi!n X1, Y1, X2, Y2, X3, Y3, ... , X8, Y8. Do
các quân hu phi n$m trên các ct khác nhau  không th &n l0n nhau, nên ta
có ngay giá tr ca các to  X, và li gii lúc này có dng :
[ 1/Y1, 2/Y2, 3/Y3, ... , 8/Y8 ]
Cho !n lúc này, bài toán tám quân hu ch" t ra i vi bàn c 8 × 8. Tuy
nhiên, li gii phi d, ki!n c cho trng hp t(ng quát khi lp trình. / ây,
ta s- thy r$ng chính trng hp t(ng quát li n gin hn bài toán ban u. Bàn
c 8 × 8 ch" là mt trng hp riêng.
) gii quy!t cho trng hp t(ng quát, ta chuyn kích thc 8 quân hu
thành mt s quân hu bt k nào ó (mi ct mt quân hu), k c s ct b$ng
không. Ta xây d,ng quan h solution t' hai tình hung sau :
1. Danh sách các quân hu rng : danh sách rng c#ng mt li gii
không xy ra s, tn công nào.
solution( [ ] ).
2. Danh sách các quân hu khác rng và có dng nh sau :
[ X/Y | Others ]
K thut lp trình Prolog 149
Trong trng hp th hai, quân hu th nht n$m trên ô X/Y, còn nhng quân
hu khác n$m trong danh sách Others. N!u danh sách này mt li gii, thì
nhng iu kin sau ây phi c tho mãn :
1. Nhng quân hu trong danh sách Others không th tn công l0n nhau,
iu này nói lên r$ng Others c#ng là mt li gii.
2. V trí XY ca nhng quân hu phi n$m gia 1 và 8.
3. Mt quân hu ti v trí X/Y không th tn công mt quân hu nào khác
trong danh sách Others.
)i vi iu kin th nht, quan h solution phi c gi mt cách 
quy.
)iu kin th hai nói lên r$ng Y phi thuc v danh sách [ 1, 2, 3, 4,
5, 6, 7, 8 ]. / ây, ta không cn quan m !n v trí X, vì nó phi tng hp
vi danh sách k!t qu tr v nh ta ã xác nh ngay t' u. Ngha X phi
thuc v nhng giá tr ã c n nh tng ng.
Gi s iu kin th ba c gii quy!t nh quan h noattack, chng trình
Prolog cho quan h solution nh sau :
solution( [ X/Y | Others ] ) :-
solution( Others ),
member( Y, [ 1, 2, 3, 4, 5, 6, 7, 8 ] ),
noattack( X/Y, Others ).
Bây gi ta cn tìm quan h noattack. Ta thy :
1. N!u danh sách Rlist rng, khi ó noattack úng, vì không quân
hu nào tn công quân hu ti X/Y nào ó.
noattack( _, [ ] ).
2. N!u danh sách Rlist khác rng, khi ó có dng [ R1 | Rlist1 ]
hai iu kin sau ây phi c tho mãn :
(a) Quân hu ti ô R không th tn công quân hu ti ô R1, và
(b) Quân hu ti ô R không th tn công quân hu nào trong Rlist1.
) mt quân hu không th tn công quân hu khác, thì chúng không th n$m
trên cùng hàng, cùng ct và cùng ng chéo chính hoc ph. Ta bi!t chc chn
r$ng các quân hu ã n$m trên các ct phân bit nhau do mô hình li gii ã n
nh. Bây gi ta cn ch" ra r$ng :
Các to  Y ca các quân hu phi phân bit nhau, và
Các quân hu không th n$m trên cùng ng chéo chính hoc ph. ngha
là khong cách gia các ô trên trc X phi khác vi các ô trên trc Y.
150 Lp trình lägich trong Prolog
noattack( X/Y, [ X1/Y2 | Others ] ) :-
Y =\= Y1,
Y1 - Y =\= X1 - X,
Y1 - Y =\= X - X1,
noattack( X/Y, Others ).
Di ây là chng trình Prolog y  th nht có cha danh sách li gii là
quan h model. Mô hình làm cho vic m li gii cho bài toán m quân hu tr
nên n gin hn.
% chng trình th nht gii bài toán tám quân hu
% The problem of the eight queens - Program 1
% −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
solution( [ ] ).
solution( [ X/Y | Others ] ) :-
solution( Others ),
ismember( Y, [ 1, 2, 3, 4, 5, 6, 7, 8 ] ),
noattack( X/Y, Others ).
noattack( _ , [ ] ).
noattack( X/Y, [ X1/Y1 | Others ] ) :-
Y =\= Y1,
Y1 – Y =\= X1 - X,
Y1 – Y =\= X - X1,
noattack( X/Y, Others ).
ismember( X , [ X | L ] ).
ismember( X, [ Y | L ] ) :-
ismember( X, L ).
model( [ 1/Y1, 2/Y2, 3/Y3, 4/Y4, 5/Y5, 6/Y6, 7/Y7, 8/Y8
] ).
?- model( S ), solution( S ).
S = [1/4, 2/2, 3/7, 4/3, 5/6, 6/8, 7/5, 8/1] ;
S = [1/5, 2/2, 3/4, 4/7, 5/3, 6/8, 7/6, 8/1] ;
S = [1/3, 2/5, 3/2, 4/8, 5/6, 6/4, 7/7, 8/1] ;
S = [1/3, 2/6, 3/4, 4/2, 5/8, 6/5, 7/7, 8/1] ;
S = [1/5, 2/7, 3/1, 4/3, 5/8, 6/6, 7/4, 8/2] ;
S = [1/4, 2/6, 3/8, 4/3, 5/1, 6/7, 7/5, 8/2]
Yes
S dng v t' not, ta vi!t li chng trình nh sau :
solution( [ ] ).
solution( [ X/Y | Others ] ) :-
K thut lp trình Prolog 151
solution( Others ),
member( Y, [ 1, 2, 3, 4, 5, 6, 7, 8 ] ),
not( attack( X/Y, Others )).
attack( X/Y, Others ) :-
member( X1/Y1, Others ),
( Y1 = Y,
Y1 is Y + X1 - X;
Y1 is Y - X1 + X ).
member( A, [ A | L ] ).
member( A, [ B | L ] ) :-
member( A, L).
% Mô hình li gii
model( [ 1/Y1, 2/Y2, 3/Y3, 4/Y4, 5/Y5, 6/Y6, 7/Y7, 8/Y8
] ).
?- model( S ), solution( S ).
S = [1/1, 2/1, 3/1, 4/1, 5/1, 6/1, 7/1, 8/1] ;
S = [1/1, 2/8, 3/1, 4/1, 5/1, 6/1, 7/1, 8/1] ;
S = [1/2, 2/8, 3/1, 4/1, 5/1, 6/1, 7/1, 8/1] ;
S = [1/1, 2/1, 3/7, 4/1, 5/1, 6/1, 7/1, 8/1] ;
S = [1/3, 2/1, 3/7, 4/1, 5/1, 6/1, 7/1, 8/1] ;
S = [1/1, 2/2, 3/7, 4/1, 5/1, 6/1, 7/1, 8/1]
Yes
>4 GE"a!,@e!
Trong chng trình th nht, ta ã a ra li gii biu din bàn c có dng :
[ 1/Y1, 2/Y2, 3/Y3, ... , 8/Y8 ]
do mi ct ch" t úng mt quân hu. Th,c ra, ta không mt thông tin n!u b+ i
các to  X. Ta có th biu din bàn c ch" vi các to  Y ca các quân hu :
[ Y1, Y2, Y3, ... , Y8 ]
) không xy ra các quân hu n$m trên cùng ct, cn phi b trí mi quân
hu mt hàng. T' ây ta t ra ràng buc cho các to  Y : mi hàng 1, 2, 3, ...,
8 ca bàn c ch" c phép t duy nht mt quân hu. Ta nhn thy r$ng mi
li gii mt hoán v ca danh sách các s 1 .. 8 sao cho th t, ca mi con s
là khác nhau :
[ 1, 2, 3, 5, 6, 7, 8 ]
Mi hoán v ca danh sách là mt li gii S sao cho các quân hu trng thái
an toàn (không &n c l0n nhau). Ta có :
152 Lp trình lägich trong Prolog
solution( S ) :-
permutation( [ 1, 2, 3, 5, 6, 7, 8 ], S ),
insafety( S ).
Trong chng 1 trc ây, ta ã xây d,ng quan h permutation, bây gi ta
cn nh ngha quan h safety. Xy ra hai trng hp nh sau :
1. N!u danh sách S rng, khi ó S c#ng là li gii, vì không có quân hu nào
tn công quân hu nào.
insafety( [ ] ).
2. N!u danh sách S khác rng, khi ó S dng [ Queen | Others ].
Ta thy S li gii n!u các quân hu trong Others trng thái an
toàn và quân hu Queen không th tn công quân hu nào trong Others.
T' ó ta có :
insafety( [ ] ).
insafety( [ Queen | Others ] ) :-
insafety( Others ),
noattack( Queen, Others ).
Trong nh ngha insafety, quan h noattack t+ ra tinh t! hn so vi
c#ng cùng quan h này trong chng trình 1 trên ây. Khó kh&n n$m ch v trí
ca mt quân hu ch" c xác nh bi các to  Y, mà vng mt to  X. )
nh ngha quan h noattack, ta tìm cách khái quát vn  nh nh minh ho
hình di ây.
Hình II.8. Khong cách gia to  X ca Queen và to  X ca Others1.
(b) Khong cách gia to  X ca Queen và to  X ca Others3.
Ta thy r$ng s dng ích :
noattack( Queen, Others )
(a) (b)
Others
Queen
khong cách to X = 1 khong cách to X = 3