Tải bản đầy đủ (.pdf) (92 trang)

Tài liệu Lập trình Prolog_chương 4-5 ppt

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (753.96 KB, 92 trang )


CHặNG 4
Cỏỳu truùc danh saùch
Chổồng naỡy trỗnh baỡy khaùi nióỷm vóử danh saùch, mọỹt trong nhổợng cỏỳu truùc
õồn giaớn nhỏỳt vaỡ thọng duỷng nhỏỳt, cuỡng vồùi nhổợng chổồng trỗnh tióu bióứu
minh hoaỷ caùch vỏỷn duỷng danh saùch trong Prolog. Cỏỳu truùc danh saùch taỷo
nón mọỹt mọi trổồỡng lỏỷp trỗnh thuỏỷn tióỷn cuớa ngọn ngổợ Prolog.
I. Bióứu dióựn cỏỳu truùc danh saùch
Danh saùch laỡ kióứu cỏỳu truùc dổợ lióỷu õổồỹc sổớ duỷng rọỹng raợi trong caùc ngọn
ngổợ lỏỷp trỗnh phi sọỳ. Mọỹt danh saùch laỡ mọỹt daợy bỏỳt kyỡ caùc õọỳi tổồỹng. Khaùc vồùi
kióứu dổợ lióỷu tỏỷp hồỹp, caùc õọỳi tổồỹng cuớa danh saùch coù thóứ truỡng nhau (xuỏỳt
hióỷn nhióửu lỏửn) vaỡ mọựi vở trờ xuỏỳt hióỷn cuớa õọỳi tổồỹng õóửu coù yù nghộa.
Danh saùch laỡ caùch dióựn õaỷt ngừn goỹn cuớa kióứu dổợ lióỷu haỷng phổùc hồỹp
trong Prolog. Haỡm tổớ cuớa danh saùch laỡ dỏỳu chỏỳm .. Do vióỷc bióứu dióựn danh
saùch bồới haỡm tổớ naỡy coù thóứ taỷo ra nhổợng bióứu thổùc mỏỷp mồỡ, nhỏỳt laỡ khi xổớ lyù
caùc danh saùch gọửm nhióửu phỏửn tổớ lọửng nhau, cho nón Prolog quy ổồùc õỷt daợy
caùc phỏửn tổớ cuớa danh saùch giổợa caùc cỷp moùc vuọng.
Chúng haỷn .(a,.(b,[ ])). Laỡ danh saùch [ a, b ].
Danh saùch caùc phỏửn tổớ anne, tennis, tom, skier (tón ngổồỡi) õổồỹc vióỳt :
[ anne, tennis, tom, skier ]
chờnh laỡ haỡm tổớ :
. ( anne, .( tennis, .( tom, .( skier, [ ] ) ) ) )
Caùch vióỳt daỷng cỷp moùc vuọng chố laỡ xuỏỳt hióỷn bón ngoaỡi cuớa mọỹt danh
saùch. Nhổ õaợ thỏỳy ồớ muỷc trổồùc, moỹi õọỳi tổồỹng cỏỳu truùc cuớa Prolog õóửu coù
bióứu dióựn cỏy. Danh saùch cuợng khọng nũm ngoaỷi lóỷ, cuợng coù cỏỳu truùc cỏy.
95
96 Láûp trçnh lägich trong Prolog
Lm cạch no âãø biãøu diãùn danh sạch båíi mäüt âäúi tỉåüng Prolog chøn ?
Cọ hai kh nàng xy ra l danh sạch cọ thãø räùng hồûc khäng. Nãúu danh sạch
räùng, nọ âỉåüc viãút dỉåïi dảng mäüt ngun tỉí :
[ ]


Nãúu danh sạch khạc räùng, cọ thãø xem nọ âỉåüc cáúu trục tỉì hai thnh pháưn
(pair syntax) :
1. Thnh pháưn thỉï nháút, âỉåüc gi l âáưu (head) ca danh sạch.
2. Thnh pháưn thỉï hai, pháưn cn lải ca danh sạch (trỉì ra pháưn âáưu),
âỉåüc gi l âi (tail) ca danh sạch, cng l mäüt danh sạch.
Trong vê dủ trãn thç âáưu l anne, cn âi l danh sạch :
[ tennis, tom, skier ]
Nọi chung, âáưu ca danh sạch cọ thãø l mäüt âäúi tỉåüng báút k ca Prolog,
cọ thãø l cáy hồûc biãún, nhỉng âi phi l mäüt danh sạch. Hçnh I.1. Biãøu diãùn
dảng cáy ca danh sạch mä t cáúu trục cáy ca danh sạch â cho :
.
anne . âi cng l danh sạch
âáưu tennis .
tom
.
skier [ ]

Hçnh I.1. Biãøu diãùn dảng cáy ca danh sạch
Vç âi tail l mäüt danh sạch, nãn tail cọ thãø räùng, hồûc lải cọ thãø âỉåüc tảo
thnh tỉì mäüt âáưu head v mäüt âi tail khạc.
Chụ ràòng danh sạch räùng xút hiãûn trong säú cạc hảng, vç ràòng pháưn tỉí
cúi cng cọ thãø xem l danh sạch chè gäưm mäüt pháưn tỉí duy nháút cọ pháưn
âi l mäüt danh sạch räùng:
[ skier ]
Vê dủ trãn âáy minh hoả ngun l cáúu trục dỉỵ liãûu täøng quạt trong
Prolog ạp dủng cho cạc danh sạch cọ âäü di tu .
?- L1 = [ a, b, c ].
?- L2 = [ a, a, a ].
Cỏỳu truùc danh saùch 97
L1 = [ a, b, c ]

L2 = [ a, a, a ]
?- Leisure1 = [ tennis, music, [ ] ].
?- Leisure2 = [ sky, eating ],
?- L = [ anne, Leisure1, tom, Leisure2 ].
Leisure1 = [ tennis, music ]
Leisure2 = [ sky, eating ]
L = [ anne, [ tennis, music ], tom, [ sky, eating ] ]
Nhổ vỏỷy, caùc phỏửn tổớ cuớa mọỹt danh saùch coù thóứ laỡ caùc õọỳi tổồỹng coù kióứu
bỏỳt kyỡ, kóứ caớ kióứu danh saùch. Thọng thổồỡng, ngổồỡi ta xổớ lyù õuọi cuớa danh
saùch nhổ laỡ mọỹt danh saùch. Chúng haỷn, danh saùch :
L = [ a, b, c ]
coù thóứ vióỳt :
tail = [ b, c ] vaỡ L = .(a, tail)
óứ bióứu dióựn mọỹt danh saùch õổồỹc taỷo thaỡnh tổỡ õỏửu (Head) vaỡ õuọi (Tail),
Prolog sổớ duỷng kyù hióỷu | (split) õóứ phỏn caùch phỏửn õỏửu vaỡ phỏửn õuọi nhổ
sau :
L = [ a | Tail ]
Kyù hióỷu | õổồỹc duỡng mọỹt caùch rỏỳt tọứng quaùt bũng caùch vióỳt mọỹt sọỳ phỏửn
tổớ tuyỡ yù cuớa danh saùch trổồùc | rọửi danh saùch caùc phỏửn tổớ coỡn laỷi. Danh saùch
bỏy giồỡ õổồỹc vióỳt laỷi nhổ sau :
[ a, b, c ] = [ a | [ b, c ] ] = [ a, b | [ c ] ] = [ a, b, c | [ ] ]
Sau õỏy laỡ mọỹt sọỳ caùch vióỳt danh saùch :
Kióứu hai thaỡnh phỏửn Kióứu lióỷt kó phỏửn tổớ
[ ] [ ]
[ a | [ ] ] [ a ]
[ a | b | [ ] ] [ a, b ]
[ a | X ] [ a | X ]
[ a | b | X ] [ a, b | X ]
[ X
1

| [ [ X
n
| [ ] ] ] ] [ X
1
, , X
n
]
Ta coù thóứ õởnh nghộa danh saùchtheo kióứu õóỷ quy nhổ sau :
List ồ [ ]
List ồ [ Element | List ]
98 Láûp trçnh lägich trong Prolog
II. Mäüt säú vë tỉì xỉí l danh sạch ca Prolog
SWI-Prolog cọ sàơn mäüt säú vë tỉì xỉí l danh sạch nhỉ sau :
Vë tỉì nghéa
append(List1, List2, List3)
Ghẹp hai danh sạch List1 v List2 thnh List3.
member(Elem, List)
Kiãøm tra Elem cọ l pháưn tỉí ca danh sạch List hay
khäng, nghéa l Elem håüp nháút âỉåüc våïi mäüt trong
cạc pháưn tỉí ca List.
nextto(X, Y, List)
Kiãøm tra nãúu pháưn tỉí Y cọ âỉïng ngay sau pháưn tỉí X
trong danh sạch List hay khäng.
delete(List1, Elem, List2)
Xoạ khi danh sạch List1 nhỉỵng pháưn tỉí håüp nháút
âỉåüc våïi Elem âãø tr vãư kãút qu List2.
select(Elem, List, Rest)
Láúy pháưn tỉí Elem ra khi danh sạch List âãø tr vãư
nhỉỵng pháưn tỉí cn lải trong Rest, cọ thãø dng âãø
chn mäüt pháưn tỉí vo danh sạch.

nth0(Index, List, Elem)
Kiãøm tra pháưn tỉí thỉï Index (tênh tỉì 0) ca danh
sạch List cọ phi l Elem hay khäng.
nth1(Index, List, Elem)
Kiãøm tra pháưn tỉí thỉï Index (tênh tỉì 1) ca danh sạch
List cọ phi l Elem hay khäng.
last(List, Elem)
Kiãøm tra pháưn tỉí âỉïng cúi cng trong danh sạch
List cọ phi l Elem hay khäng.
reverse(List1, List2)
Nghëch âo thỉï tỉû cạc pháưn tỉí ca danh sạch List1
âãø tr vãư kãút qu List2.
permutation(List1, List2)
Hoạn vë danh sạch List1 thnh danh sạch List2.
flatten(List1, List2)
Chuøn danh sạch List1 chỉïa cạc pháưn tỉí báút k
thnh danh sạch phàóng List2.
Vê dủ : flatten([a, [b, [c, d], e]], X).
cho kãút qu X = [a, b, c, d, e].
sumlist(List, Sum)

Tênh täøng cạc pháưn tỉí ca danh sạch List chỉïa ton
säú âãø tr vãư kãút qu Sum.
numlist(Low, High, List)
Nãúu Low v High l cạc säú sao cho Low =< High, thç
tr vãư danh sạch List = [Low, Low+1, , High].
Chụ mäüt säú vë tỉì xỉí l danh sạch cọ thãø sỉí dủng cho mi rng büc, kãø
c khi cạc tham âäúi âãưu l biãún.
Trong Prolog, táûp håüp âỉåüc biãøu diãùn båíi danh sạch, tuy nhiãn, thỉï tỉû cạc
pháưn tỉí trong mäüt táûp håüp l khäng quan trng, cạc âäúi tỉåüng d xút hiãûn

Cáúu trục danh sạch 99
nhiãưu láưn chè âỉåüc xem l mäüt pháưn tỉí ca táûp håüp. Cạc phẹp toạn vãư danh
sạch cọ thãø ạp dủng cho cạc táûp håüp. Âọ l :
• Kiãøm tra mäüt pháưn tỉí cọ màût trong mäüt danh sạch tỉång tỉû viãûc kiãøm tra
mäüt pháưn tỉí cọ thüc vãư mäüt táûp håüp khäng ?
• Ghẹp hai danh sạch âãø nháûn âỉåüc mäüt danh sạch thỉï ba tỉång ỉïng våïi
phẹp håüp ca hai táûp håüp.
• Thãm mäüt pháưn tỉí måïi, hay loải b mäüt pháưn tỉí.
Prolog cọ sàơn mäüt säú vë tỉì xỉí l táûp håüp nhỉ sau :
Vë tỉì nghéa
is_set(Set)
Kiãøm tra Set cọ phi l mäüt táûp håüp hay khäng
list_to_set(List, Set)
Chuøn danh sạch List thnh táûp håüp Set giỉỵ
ngun thỉï tỉû cạc pháưn tỉí ca List (nãúu List cọ cạc
pháưn tỉí trng nhau thç chè láúy pháưn tỉí gàûp âáưu
tiãn). Vê dủ : list_to_set([a,b,a], X) cho kãút qu
X = [a,b].
intersection(Set1, Set2, Set3)
Phẹp giao ca hai táûp håüp Set1 v Set2 l Set3.
subtract(Set, Delete, Result)
Tr vãư kãút qu phẹp hiãûu ca hai táûp håüp Set v
Delete l Result (l táûp Set sau khi â xoạ hãút cạc
pháưn tỉí ca Delete cọ màût trong âọ).
union(Set1, Set2, Set3)
Tr vãư kãút qu phẹp håüp ca hai táûp håüp Set1 v
Set2 l Set3.
subset(Subset, Set)
Kiãøm tra táûp håüp Subset cọ l táûp håüp con ca Set
hay khäng.

III. Cạc thao tạc cå bn trãn danh sạch
III.1. Xáy dỉûng lải mäüt säú vë tỉì cọ sàơn
Sau âáy ta s trçnh by mäüt säú thao tạc cå bn trãn danh sạch bàòng cạch
xáy dỉûng lải mäüt säú vë tỉì cọ sàơn ca Prolog.
III.1.1. Kiãøm tra mäüt pháưn tỉí cọ màût trong danh sạch
Prolog kiãøm tra mäüt pháưn tỉí cọ màût trong mäüt danh sạch nhỉ sau :
member(X, L)
100 Láûp trçnh lägich trong Prolog
trong âọ, X l mäüt pháưn tỉí v L l mäüt danh sạch. Âêch member(X, L) âỉåüc
tho mn nãúu X xút hiãûn trong L. Vê dủ :
?- member( b, [ a, b, c ] )
Yes
?- member( b, [ a, [ b, c ] ] )
No
?- member( [ b, c], [ a, [ b, c ] ] )
Yes
Tỉì cạc kãút qu trãn, ta cọ thãø gii thêch quan hãû member(X, L) nhỉ sau :
Pháưn tỉí X thüc danh sạch L nãúu :
1. X l âáưu ca L, hồûc nãúu
2. X l mäüt pháưn tỉí ca âi ca L.
Ta cọ thãø viãút hai âiãưu kiãûn trãn thnh hai mãûnh âãư, mãûnh âãư thỉï nháút l
mäüt sỉû kiãûn âån gin, mãûnh âãư thỉï hai l mäüt lût :
member( X, [ X | Tail ] ).
member( X, [ Head | Tail ] ) :- member( X, Tail ).
hồûc :
member(X, [X|T]).
member(X, [_|T]) :- member(X, T).
III.1.2. Ghẹp hai danh sạch
Âãø ghẹp hai danh sạch, Prolog cọ hm :
append( L1, L2, L3).

trong âọ, L1 v L2 l hai danh sạch, L3 l kãút qu ca phẹp ghẹp L1 v L2. Vê
dủ :
?- append( [ a, b ], [ c, d ], [ a, b, c, d ] ).
Yes
?- append( [ a, b ], [ c, d ], [ a, b, a, c ] ).
No
Hm append hoảt âäüng phủ thüc tham âäúi âáưu tiãn L1 theo cạch nhỉ
sau :
1. Nãúu tham âäúi âáưu tiãn l danh sạch räùng, thç tham âäúi thỉï hai v thỉï
ba phi l mäüt danh sạch duy nháút, gi l L. Ta viãút trong Prolog nhỉ
sau :
append( [ ], L, L).
Cáúu trục danh sạch 101
2. Nãúu tham âäúi âáưu tiãn ca append l danh sạch khạc räùng, thç nọ gäưm
mäüt âáưu v mäüt âi nhỉ sau
[ X | L1 ]
Kãút qu phẹp ghẹp danh sạch l danh sạch [ X | L3 ], våïi L3 l phẹp
ghẹp ca L1 v L2. Ta viãút trong Prolog nhỉ sau :
append( [ X | L1 ], L2, [ X | L3 ] ) :- append( L1, L2, L3 ).
Hçnh 4.2 dỉåïi âáy minh hoả phẹp ghẹp hai danh sạch [ X | L1 ] v L2.
[ X | L1 ]
XL3
[ X | L3 ]
XL1
L3
L2

Hçnh III.1. Ghẹp hai danh sạch [ X | L1 ] v L2 thnh [ X | L3 ].
Ta cọ cạc vê dủ sau :
?- append( [ a, b, c ], [ 1, 2, 3 ], L ).

L = [ a, b, c, 1, 2, 3 ]
?- append( [ a, [ b, c ], d ], [ a, [ ], b ], L ] ).
L = [ a, [ b, c ], d, a, [ ], b ]
Th tủc append âỉåüc sỉí dủng ráút mãưm do theo nhiãưu cạch khạc nhau.
Chàóng hản Prolog âỉa ra bäún phỉång ạn âãø phán tạch mäüt danh sạch â
cho thnh hai danh sạch måïi nhỉ sau :
?- append( L1, L2, [ a, b, c ] ).
L1 = [ ]
L2 = [ a, b, c ];
L1 = [ a ]
L2 = [ b, c ];
L1 = [ a, b ]
L2 = [ c ];
L1 = [ a, b, c ]
L2 = [ ];
Yes
102 Lỏỷp trỗnh lọgich trong Prolog
Sổớ duỷng append, ta cuợng coù thóứ tỗm kióỳm mọỹt sọỳ phỏửn tổớ trong mọỹt danh
saùch. Chúng haỷn, tổỡ danh saùch caùc thaùng trong nm, ta coù thóứ tỗm nhổợng
thaùng õổùng trổồùc mọỹt thaùng õaợ cho, giaớ sổớ thaùng nm (May) :
?- append( Before, [ May | After ] ,
[ jan, fev, mar, avr, may, jun, jul, aut, sep, oct, nov, dec ] ).
Before = [ jan, fev, mar, avr ]
After = [ jun, jul, aut, sep, oct, nov, dec ]
Yes
Thaùng õổùng ngay trổồùc vaỡ thaùng õổùng ngay sau thaùng nm nhỏỷn õổồỹc nhổ
sau :
?- append( _, [ Month1, may, Month2 | _ ] ,
[ jan, fev, mar, avr, may, jun, jul, aut, sep, oct, nov, dec ] ).
Month1 = avr

Month2 = jun
Yes
Bỏy giồỡ cho trổồùc danh saùch :
L1 = [ a, b, z, z, c, z, z, z, d, e ]
Ta cỏửn xoùa caùc phỏửn tổớ õổùng sau ba chổợ z lión tióỳp, kóứ caớ ba chổợ z :
?- L1 = [ a, b, z, z, c, z, z, z, d, e ],
append( L2, [ z, z, z | _ ], L1 ).
L1 = [ a, b, z, z, c, z, z, z, d, e ]
L2 = [ a, b, z, z, c ]
Trổồùc õỏy ta õaợ õởnh nghộa quan hóỷ member( X, L ) õóứ kióứm tra mọỹt phỏửn
tổớ X coù mỷt trong mọỹt danh saùch L khọng. Bỏy giồỡ bũng caùch sổớ duỷng
append, ta coù thóứ õởnh nghộa laỷi member nhổ sau :
member1( X, L ) :- append( L1, [ X | L2], L).
Móỷnh õóử naỡy coù nghộa : nóỳu X coù mỷt trong danh saùch L thỗ L coù thóứ õổồỹc
phỏn taùch thaỡnh hai danh saùch, vồùi X laỡ õỏửu cuớa danh saùch thổù hai. ởnh
nghộa member1 hoaỡn toaỡn tổồng õổồng vồùi õởnh nghộa member.
õỏy ta sổớ duỷng hai tón khaùc nhau õóứ phỏn bióỷt hai caùch caỡi õỷt Prolog.
Ta cuợng coù thóứ õởnh nghộa laỷi member1 bũng caùch sổớ duỷng bióỳn nỷc danh
(anonymous variable) :
member1( X, L ) :- append( _ , [ X | _ ], L).
Cáúu trục danh sạch 103
Mãûnh âãư 2 ca append
So khåïp :
L1 = [ X | L1’ ]
[ b | L2 ] = L2’
[ a, b, c ] = [ X | L3’ ]
Tỉì âọ kẹo theo :
X = a, L3’ = [ b, c ]
Mãûnh âãư 1 ca append
So khåïp :

L1’ = [ ]
[ b | L2 ] = [ b, c ]
Tỉì âọ kẹo theo :
L2 = [ c ]
thnh cäng
Mãûnh âãư 1 ca append
So khåïp :
L1 = [ ]
[ b | L2 ] = [ a, b, c ]
Tháút bải vç b ≠ a

append( L1’, [ b | L2 ], [ b, c ] )
append( L1, [ b | L2 ], [ a, b, c ]
)
member1( b, [ a, b, c ] )

Hçnh III.2. Th tủc member1 tçm tưn tỉû mäüt âäúi tỉåüng trong danh sạch â cho.
So sạnh hai cạch ci âàût khạc nhau vãư quan hãû thnh viãn, ta nháûn tháúy
nghéa th tủc trong âënh nghéa member âỉåüc thãø hiãûn ráút r :
Trong member, âãø kiãøm tra pháưn tỉí X cọ màût trong mäüt danh sạch L
khäng,
1. Trỉåïc tiãn kiãøm tra pháưn tỉí âáưu ca L l âäưng nháút våïi X, nãúu khäng,
2. Kiãøm tra ràòng X cọ màût trong pháưn âi ca L.
Nhỉng trong trỉåìng håüp âënh nghéa member1, ta tháúy hon ton nghéa
khai bạo m khäng cọ nghéa th tủc.
Âãø hiãøu âỉåüc cạch member1hoảt âäüng nhỉ thãú no, ta hy xem xẹt quạ
trçnh Prolog thỉûc hiãûn cáu hi :
?- member1( b, [ a, b, c ] ).
104 Láûp trçnh lägich trong Prolog
Cạch tçm ca th tủc member1 trãn âáy tỉång tỉû member, bàòng cạch

duût tỉìng pháưn tỉí, cho âãún khi tçm tháúy âäúi tỉåüng cáưn tçm, hồûc danh sạch
â cản.
III.1.3. Bäø sung mäüt pháưn tỉí vo danh sạch
Phỉång phạp âån gin nháút âãø bäø sung mäüt pháưn tỉí vo danh sạch l âàût
nọ åí vë trê âáưu tiãn, âãø nọ tråí thnh âáưu. Nãúu X l mäüt âäúi tỉåüng måïi, cn L
l danh sạch cáưn bäø sung thãm, thç danh sạch kãút qu s l :
[ X | L ]
Ngỉåìi ta khäng cáưn viãút th tủc âãø bäø sung mäüt pháưn tỉí vo danh sạch.
Båíi vç viãûc bäø sung cọ thãø âỉåüc biãøu diãùn dỉåïi dảng mäüt sỉû kiãûn nãúu cáưn :
insert( X, L, [ X | L ] ).
III.1.4. Loải b mäüt pháưn tỉí khi danh sạch
Âãø loải b mäüt pháưn tỉí X khi danh sạch L, ngỉåìi ta xáy dỉûng quan hãû :
remove( X, L, L1 )
trong âọ, L1 âäưng nháút våïi L, sau khi X bë loải b khi L. Th tủc remove cọ
cáúu trục tỉång tỉû member. Ta cọ thãø láûp lûn nhỉ sau
1. Nãúu pháưn tỉí X l âáưu ca danh sạch, thç kãút qu l âi ca danh
sạch.
2. Nãúu khäng, tçm cạch loải b X khi pháưn âi ca danh sạch.
remove( X, [ X | Tail ], Tail ).
remove( X, [ Y | Tail ], [ Y | Tail1 ] ) :-
remove( X, Tail, Tail1 ).
Tỉång tỉû th tủc member, th tủc remove mang tênh khäng xạc âënh.
Nãúu cọ nhiãưu pháưn tỉí l X cọ màût trong danh sạch, thç remove cọ thãø xoạ báút
k pháưn tỉí no, do quạ trçnh quay lui. Tuy nhiãn, mäùi láưn thỉûc hiãûn, remove
chè xoạ mäüt pháưn tỉí l X m khäng âủng âãún nhỉỵng pháưn tỉí khạc. Vê dủ :
?- remove( a, [ a, b, a, a ], L ).
L = [ b, a, a ];
L = [ a, b, a ];
L = [ a, b, a ]
No

Cáúu trục danh sạch 105
Th tủc remove tháút bải nãúu danh sạch khäng chỉïa pháưn tỉí cáưn xoạ.
Ngỉåìi ta cọ thãø sỉí dủng remove trong mäüt khêa cảnh khạc, mủc âêch âãø bäø
sung mäüt pháưn tỉí måïi vo báút cỉï âáu trong danh sạch.
Vê dủ, nãúu ta mún âàût pháưn tỉí a vo tải mi vë trê báút k trong danh
sạch [ 1, 2, 3 ], chè cáưn âàût cáu hi : Cho biãút danh sạch L nãúu sau khi xoạ a,
ta nháûn âỉåüc danh sạch [ 1, 2, 3 ] ?
?- remove( a, L, [ 1, 2, 3 ] ).
L = [ a, 1, 2, 3 ];
L = [ 1, a, 2, 3 ];
L = [ 1, 2, a, 3 ];
L = [ 1, 2, 3, a ]
No
Mäüt cạch täøng quạt, phẹp toạn chn insert mäüt pháưn tỉí X vo mäüt danh
sạch List âỉåüc âënh nghéa båíi th tủc remove bàòng cạch sỉí dủng mäüt danh
sạch låïn hån LargerList lm tham âäúi thỉï hai :
insert( X, List, LargerList ) :-
remove( X, LargerList, List ).
Ta â âënh nghéa quan hãû thüc vãư trong th tủc member1 bàòng cạch sỉí
dủng th tủc append. Tuy nhiãn, ta cng cọ thãø âënh nghéa lải quan hãû
thüc vãư trong th tủc måïi member2 båíi th tủc remove bàòng cạch xem mäüt
pháưn tỉí X thüc vãư mäüt danh sạch List nãúu X bë xoạ khi List :
member2( X, List ) :-
remove( X, List, _ ).
III.1.5. Nghëch âo danh sạch
Sỉí dủng append, ta cọ thãø viãút th tủc nghëch âo mäüt danh sạch nhỉ
sau :
reverse ( [ ], [ ] ).
reverse ( [ X | Tail ], R ) :-
reverse (Tail, R1 ),

append(R1, [X], R).
?- reverse( [ a, b, c , d, e, f ] , L).
L = [f, e, d, c, b, a]
Yes
106 Lỏỷp trỗnh lọgich trong Prolog
Sau õỏy laỡ mọỹt thuớ tuỷc khaùc õóứ nghởch õaớo mọỹt danh saùch nhổng coù sổớ
duỷng haỡm bọứ trồỹ trong thỏn thuớ tuỷc :
revert(List, RevList) :-
rev(List, [ ], RevList).
rev([ ], R, R).
rev([H|T], S, R) :-
rev(T, [H|S], R).
?- revert( [ a, b, c , d, e, f ] , R).
R = [f, e, d, c, b, a]
Yes
Sổớ duỷng reverse, ta coù thóứ kióứm tra mọỹt danh saùch coù laỡ õọỳi xổùng
(palindrome) kay khọng :
palindrome(L) :-
reverse( L, L ).
?- palindrome([ a, b, c , d, c, b, a ]).
Yes
III.1.6. Danh saùch con
Ta xỏy dổỷng thuớ tuỷc sublist nhỏỷn hai tham õọỳi laỡ hai danh saùch L vaỡ S
sao cho S laỡ danh saùch con cuớa L nhổ sau :
?- sublist( [ c, d, e ], [ a, b, c , d, e, f ] )
Yes
?- sublist( [ c, e ], [ a, b, c , d, e, f ] )
No
Nguyón lyù õóứ xỏy dổỷng thuớ tuỷc sublist tổồng tổỷ thuớ tuỷc member1, mỷc duỡ
ồớ õỏy quan hóỷ danh saùch con tọứng quaùt hồn.


L
L
XL2
L3SL1
L2
[ X | L2 ]
L1
member( X, L )
sublist( S, L )
Hỗnh III.3. Caùc quan hóỷ member vaỡ sublist.
Cáúu trục danh sạch 107
Quan hãû danh sạch con âỉåüc mä t nhỉ sau :
S l mäüt danh sạch con ca L nãúu :
1. Danh sạch L cọ thãø âỉåüc phán tạch thnh hai danh sạch L1 v L2, v
nãúu
2. Danh sạch L2 cọ thãø âỉåüc phán tạch thnh hai danh sạch S v L3.
Nhỉ â tháúy, viãûc phán tạch cạc danh sạch cọ thãø âỉåüc mä t båíi quan hãû
ghẹp append.
Do âọ ta viãút lải trong Prolog nhỉ sau :
sublist( S, L ) :-
append( L1, L2, L ), append( S, L3, L2 ).
Ta tháúy th tủc sublist ráút mãưm do v do váûy cọ thãø sỉí dủng theo nhiãưu
cạch khạc nhau. Chàóng hản ta cọ thãø liãût kã mi danh sạch con ca mäüt
danh sạch â cho nhỉ sau :
?- sublist( S, [ a, b, c ] ).
S = [ ];
S = [ a ];
S = [ a, b ];
S = [ a, b, c ];

S = [ b ];

III.2. Hoạn vë
Âäi khi, ta cáưn tảo ra cạc hoạn vë ca mäüt danh sạch. Ta xáy dỉûng quan
hãû permutation cọ hai tham biãún l hai danh sạch, m mäüt danh sạch l hoạn
vë ca danh sạch kia. Ta s táûn dủng phẹp quay lui nhỉ sau :
?- permutation( [ a, b, c ], P ).
P = [ a, b, c ];
P = [ a, c, b ];
P = [ b, a, c ];

Ngun l hoảt âäüng ca th tủc swap dỉûa trãn hai trỉåìng håüp phán
biãût, tu theo danh sạch thỉï nháút :
1. Nãúu danh sạch thỉï nháút räùng, thç danh sạch thỉï hai cng phi räùng.
108 Láûp trçnh lägich trong Prolog
2. Nãúu danh sạch thỉï nháút khạc räùng, thç nọ s cọ dảng [ X | L ] v âỉåüc
tiãún hnh hoạn vë nhỉ sau : trỉåïc tiãn hoạn vë L âãø nháûn âỉåüc L1, sau
âọ chn X vo táút c cạc vë trê trong L1.

L1 l mäüt hoạn vë ca L
Chn X tải mäüt vë trê âãø nháûn âỉåüc mäüt hoạn vë ca [ X | L ]
X L
hoạn vë L
L1
Hçnh III.4. Mäüt cạch xáy dỉûng hoạn vë permutation ca danh sạch [ X | L ].
Ta nháûn âỉåüc hai mãûnh âãư tỉång ỉïng våïi th tủc nhỉ sau :
permutation( [ ], [ ] ).
permutation( [ X | L ], P ) :-
permutation( L, L1 ), insert( X, L1, P ).
Mäüt phỉång phạp khạc l loải b pháưn tỉí X khi danh sạch âáưu tiãn,

hoạn vë pháưn cn lải ca danh sạch ny âãø nháûn âỉåüc danh sạch P, sau âọ
thãm X vo pháưn âáưu ca P. Ta cọ chỉång trçnh khạc permutation2 nhỉ sau :
permutation2( [ ], [ ] ).
permutation2( L, [ X | P ] ) :-
remove( X, L, L1 ), permutation2( L1, P ).
Tỉì âáy, ta cọ thãø khai thạc th tủc hoạn vë, chàóng hản (chụ khi chảy
Arity Prolog cáưn g vo mäüt dáúu cháúm pháøy ; sau ->) :
?- permutation( [ red, blue, green ], P ).
P = [ red, blue, green ];
P = [ red, green, blue ];
P = [ blue, red, green ];
P = [ blue, green, red ];
P = [ green, red, blue ];
P = [ green, blue, red ];
Yes
Hồûc nãúu sỉí dủng permutation theo cạch khạc nhỉ sau :
?- permutation( L, [ a, b, c ] ).
Prolog s rng büc liãn tiãúp cho L âãø âỉa ra 6 hoạn vë khạc nhau cọ thãø.
Tuy nhiãn, nãúu NSD u cáưu mäüt gii phạp khạc, Prolog s khäng bao giåì
Cỏỳu truùc danh saùch 109
traớ lồỡi No, maỡ rồi vaỡo mọỹt voỡng lỷp vọ haỷn do phaới tỗm kióỳm mọỹt hoaùn vở
mồùi maỡ thổỷc ra khọng tọửn taỷi. Trong trổồỡng hồỹp naỡy, thuớ tuỷc permutation2
chố tỗm thỏỳy mọỹt hoaùn vở thổù nhỏỳt, sau õoù ngay lỏỷp tổùc rồi vaỡo mọỹt voỡng lỷp
vọ haỷn. Vỗ vỏỷy, cỏửn chuù yù khi sổớ duỷng caùc quan hóỷ hoaùn vở naỡy.
III.3. Mọỹt sọỳ vờ duỷ vóử danh saùch
III.3.1. Sừp xóỳp caùc phỏửn tổớ cuớa danh saùch
Xỏy dổỷng thuớ tuỷc sừp xóỳp caùc phỏửn tổớ coù cuớa mọỹt danh saùch bũng phổồng
phaùp cheỡn nhổ sau :
ins(X, [ ], [ X ]).
ins(X, [H|T], [ X,H|T ]) :-

X @=< H.
ins(X, [ H|T ], [ H|L ]) :-
X @> H, ins( X, T, L ).
?- ins(8, [ 1, 2, 3, 4, 5 ], L).
L = [1, 2, 3, 4, 5, 8]
Yes
?- ins(1, L, [ 1, 2, 3, 4, 5 ]).
L = [2, 3, 4, 5]
Yes
ins_sort([ ], [ ]).
ins_sort([H|T], L) :-
ins_sort(T, L1),
ins(H, L1, L).
?- ins_sort([3, 2, 6, 4, 7, 1], L).
L = [1, 2, 3, 4, 6, 7]
Yes
III.3.2. Tờnh õọỹ daỡi cuớa mọỹt danh saùch
Xỏy dổỷng thuớ tuỷc tờnh õọỹ daỡi hay õóỳm sọỳ lổồỹng caùc phỏửn tổớ coù mỷt trong
mọỹt danh saùch õaợ cho nhổ sau :
length( L, N ).
Xaớy ra hai trổồỡng hồỹp :
1. Nóỳu danh saùch rọựng, thỗ õọỹ daỡi N = 0.
110 Lỏỷp trỗnh lọgich trong Prolog
2. Nóỳu danh saùch khaùc rọựng, thỗ noù õổồỹc taỷo thaỡnh tổỡ danh saùch coù
daỷng :
[ head | queue ]
vaỡ coù õọỹ daỡi bũng 1 cọỹng vồùi õọỹ daỡi cuớa queue.
Ta coù chổồng trỗnh Prolog nhổ sau :
length( [ ], 0 ).
length( [ _ | Queue ], N ) :-

length(Queue, N1 ),
N is 1 + N1.
Kóỳt quaớ chaỷy Prolog nhổ sau :
?- length( [ a, b, c, d, e ], N ).
N = 5
Yes
?- length( [ a, [ b, c ], d, e ], N ).
N = 4
Yes
Ta thỏỳy rũng trong móỷnh õóử thổù hai, hai õờch cuớa phỏửn thỏn laỡ khọng
thóứ hoaùn õọứi cho nhau, vỗ rũng N1 phaới õổồỹc raỡng buọỹc trổồùc khi thổỷc hióỷn
õờch :
N is 1 + N1
Chúng haỷn, nóỳu goỹi trace, quaù trỗnh thổỷc hióỷn length( [ 1, 2, 3 ], N ) nhổ
sau :
(0) goỹi length([1, 2, 3], N) ->
(1) goỹi length([2, 3], N) ->
(2) goỹi length([3], N) ->
(3) goỹi length([ ], N) -> N = 0
(4) goỹi N is 1 + 0 -> N = 1
(5) goỹi N is 1 + 1 -> N = 2
(6) goỹi N is 1 + 2 -> N = 3
Vồùi is, ta õaợ õổa vaỡo mọỹt quan hóỷ nhaỷy caớm vồùi thổù tổỷ thổỷc hióỷn caùc õờch,
vaỡ do vỏỷy khọng thóứ boớ qua yóỳu tọỳ thuớ tuỷc trong chổồng trỗnh.
ióửu gỗ seợ xaớy ra nóỳu ta khọng sổớ duỷng is trong chổồng trỗnh. Chúng
haỷn :
length1( [ ], 0 ).
Cỏỳu truùc danh saùch 111
length1( [ _ | Queue ], N ) :-
length1( Queue, N1 ),

N = 1 + N1.
Luùc naỡy, nóỳu goỹi :
?- length1( [ a, [ b, c ], d, e ], N ).
Prolog traớ lồỡi :
N = 1 + (1 + (1 + (1 + 0)))
Yes
Pheùp cọỹng do khọng õổồỹc khồới õọỹng mọỹt caùch tổồỡng minh nón seợ khọng
bao giồỡ õổồỹc thổỷc hióỷn. Tuy nhión, ta coù thóứ hoaùn õọứi hai õờch cuớa móỷnh õóử
thổù hai trong length1 :
length1( [ ], 0 ).
length1( [ _ | Queue ], N ) :-
N = 1 + N1,
length1( Queue, N1 ).
Kóỳt quaớ chaỷy chổồng trỗnh sau khi hoaùn õọứi vỏựn y hóỷt nhổ cuợ. Bỏy giồỡ, ta
laỷi coù thóứ ruùt goỹn móỷnh õóử vóử chố coỡn mọỹt õờch :
length1( [ ], 0 ).
length2( [ _ | Queue ], 1 + N ) :-
length2( Queue, N ).
Kóỳt quaớ chaỷy chổồng trỗnh lỏửn naỡy vỏựn y hóỷt nhổ cuợ. Prolog khọng õổa
ra traớ lồỡi nhổ mong muọỳn, maỡ laỡ :
?- length1([ a, b, c, d], N).
N = 1+ (1+ (1+ (1+0)))
Yes
III.3.3. Taỷo sinh caùc sọỳ tổỷ nhión
Chổồng trỗnh sau õỏy taỷo sinh vaỡ lióỷt kó caùc sọỳ tổỷ nhión :
% Natural Numbers
nat(0).
nat(N) :- nat(M), N is M + 1.
Khi thổỷc hióỷn caùc õờch con trong cỏu hoới :
?- nat(N), write(N), nl, fail.

112 Láûp trçnh lägich trong Prolog
cạc säú tỉû nhiãn âỉåüc tảo sinh liãn tiãúp nhåì k thût quay lui. Sau khi säú tỉû
nhiãn âáưu tiãn nat(N) âỉåüc in ra nhåì write(N), hàòng fail bàõt büc thỉûc hiãûn
quay lui. Khi âọ, lût thỉï hai âỉåüc váûn dủng âãø tảo sinh säú tỉû nhiãn tiãúp
theo v cỉï thãú tiãúp tủc cho âãún khi NSD quút âënh dỉìng chỉång trçnh (^C).
Tọm tàõt chỉång 4
• Danh sạch l mäüt cáúu trục hồûc räùng, hồûc gäưm hai pháưn : pháưn âáưu l
mäüt pháưn tỉí v pháưn cn lải l mäüt danh sạch.
• Prolog qun l cạc danh sạch theo cáúu trục cáy nhë phán. Prolog cho
phẹp sỉí dủng nhiãưu cạch khạc nhau âãø biãøu diãùn danh sạch.
[ Object1, Object2, ]
hồûc [ Head | Tail ]
hồûc [ Object1, Object2, | Others ]
Våïi Tail v Others l cạc danh sạch.
• Cạc thao tạc cäø âiãøn trãn danh sạch cọ thãø láûp trçnh âỉåüc l : kiãøm tra
mäüt pháưn tỉí cọ thüc vãư mäüt danh sạch cho trỉåïc khäng, phẹp ghẹp
hai danh sạch, bäø sung hồûc loải b mäüt pháưn tỉí åí âáưu hồûc cúi danh
sạch, trêch ra mäüt danh sạch con
Bi táûp chỉång 4
1. Viãút mäüt th tủc sỉí dủng append âãø xọa ba pháưn tỉí cúi cng ca danh
sạch L, tảo ra danh sạch L1. Hỉåïng dáùn : L l phẹp ghẹp ca L1 våïi mäüt
danh sạch ca ba pháưn tỉí (â bë xọa khi L).
2. Viãút mäüt dy cạc âêch âãø xọa ba pháưn tỉí âáưu tiãn v ba pháưn tỉí cúi cng
ca mäüt danh sạch L, âãø tr vãư danh sạch L2.
3. Âënh nghéa quan hãû :
last_element( Object, List )
sao cho Object phi l pháưn tỉí cúi cng ca danh sạch List. Hy viãút
thnh hai mãûnh âãư, trong âọ cọ mäüt mãûnh âãư sỉí dủng append, mãûnh âãư
kia khäng sỉí dủng append.
4. Âënh nghéa hai vë tỉì :

Cỏỳu truùc danh saùch 113
even_length( List ) vaỡ odd_length( List )
õổồỹc thoợa maợn khi sọỳ caùc phỏn tổớ cuớa danh saùch List laỡ chụn hay leớ tổồng
ổùng. Vờ duỷ danh saùch :
[ a, b, c, d ] coù õọỹ daỡi chụn,
[ a, b, c ] coù õọỹ daỡi leợ.
5. Cho bióỳt kóỳt quaớ Prolog traớ lồỡi caùc cỏu hoới sau :
?- [1,2,3] = [1|X].
?- [1,2,3] = [1,2|X].
?- [1 | [2,3]] = [1,2,X].
?- [1 | [2,3,4]] = [1,2,X].
?- [1 | [2,3,4]] = [1,2|X].
?- b(o,n,j,o,u,r) = L.
?- bon(Y) = [X,jour].
?- X(Y) = [bon,jour].
6. Vióỳt chổồng trỗnh Prolog kióứm tra mọỹt danh saùch coù phaới laỡ mọỹt tỏỷp hồỹp
con cuớa mọỹt danh saùch khaùc khọng ? Chổồng trỗnh hoaỷt õọỹng nhổ sau :
?- subset2([4,3],[2,3,5,4]).
Yes
7. Vióỳt chổồng trỗnh Prolog õóứ lỏỳy ra caùc phỏửn tổớ tổỡ mọỹt danh saùch. Chổồng
trỗnh cuợng coù thóứ cheỡn caùc phỏửn tổớ vaỡo mọỹt danh saùch hoaỷt õọỹng nhổ
sau :
?- takeout(3,[1,2,3],[1,2]).
Yes
?- takeout(X,[1,2,3],L).
X = 1
L = [2, 3] ;
X = 2
L = [1, 3] ;
X = 3

L = [1, 2] ;
No
?- takeout(4,L,[1,2,3]).
4
L = [4, 1, 2, 3] ;
L = [1, 4, 2, 3] ;
L = [1, 2, 4, 3] ;
114 Láûp trçnh lägich trong Prolog
L = [1, 2, 3, 4] ;
No
8. Viãút vë tỉì Prolog getEltFromList(L,N,E) cho phẹp láúy ra pháưn tỉí thỉï N
trong mäüt danh sạch. Tháút bải nãúu danh sạch khäng cọ â N pháưn tỉí.
Chỉång trçnh hoảt âäüng nhỉ sau :
?- getEltFromList([a,b,c],0,X).
No
?- getEltFromList([a,b,c],2,X).
X = b
?- getEltFromList([a,b,c],4,X).
No
9. Viãút chỉång trçnh Prolog tçm pháưn tỉí låïn nháút v pháưn tỉí nh nháút trong
mäüt danh sạch cạc säú. Chỉång trçnh hoảt âäüng nhỉ sau :
?- maxmin([3,1,5,2,7,3],Max,Min).
Max = 7
Min = 1
Yes
?- maxmin([2],Max,Min).
Max = 2
Min = 2
Yes
10. Viãút chỉång trçnh Prolog chuøn mäüt danh sạch phỉïc håüp, l danh sạch

m mäùi pháưn tỉí cọ thãø l mäüt danh sạch con chỉïa cạc danh sạch con
phỉïc håüp khạc, thnh mäüt danh sạch phàóng l danh sạch chè chỉïa cạc
pháưn tỉí trong táút ca
í cạc danh sạch con cọ thãø, giỉỵ ngun thỉï tỉû lục
âáưu. Chỉång trçnh hoảt âäüng nhỉ sau :
flatten([[1,2,3],[4,5,6]], Flatlist).
Flatlist = [1,2,3,4,5,6]
Yes
flatten([[1,[hallo,[[aloha]]],2,[],3],[4,[],5,6]], Flatlist)
Flatlist = [1, hallo, aloha, 2, 3, 4, 5, 6]
Yes
11. Viãút cạc chỉång trçnh Prolog thỉûc hiãûn cạc vë tỉì xỉí l táûp håüp cho åí pháưn
l thuút (mủc II).
Cáúu trục danh sạch 115
12. Sỉí dủng vë tỉì forall âãø viãút chỉång trçnh Prolog kiãøm tra hai danh sạch
cọ råìi nhau (disjoint) khäng ? Chỉång trçnh hoảt âäüng nhỉ sau :
?- disjoint([a,b,c],[d,g,f,h]).
Yes
?- disjoint([a,b,c],[f,a]).
No
13. Vë tỉì forall(Cond, Action) thỉûc hiãûn kiãøm tra sỉû so khåïp tỉång ỉïng giỉỵa
Cond, thỉåìng kãút håüp våïi vë tỉì member, v Action. Vê dủ dỉåïi âáy kiãøm
tra viãûc thỉûc hiãûn cạc phẹp toạn säú hc trong danh sạch L l âụng âàõn.
?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]), Result =:=
Formula).
Result = _G615
Formula = _G616
Yes
14. Sỉí dủng vë tỉì forall âãø viãút chỉång trçnh Prolog kiãøm tra mäüt danh sạch
cọ l mäüt táûp håüp con ca mäüt danh sạch khạc hay khäng ? Chỉång trçnh

hoảt âäüng nhỉ sau :
?- subset3([a,b,c],[c,d,a,b,f]).
Yes
?- subset3([a,b,q,c],[d,a,c,b,f])
No
15. Sỉí dủng vë tỉì append ghẹp hai danh sạch âãø viãút cạc chỉång trçnh
Prolog thỉûc hiãûn cạc viãûc sau :
prefixe(L1, L2) danh sạch L1 âỉïng trỉåïc (prefixe list) danh sạch L2.
suffixe(L1, L2) danh sạch L1 âỉïng sau (suffixe list) danh sạch L2.
isin(L1, L2) cạc pháưn tỉí ca danh sạch L1 cọ màût trong danh sạch
L2.
16. Sỉí dủng phỉång phạp Quicksort viãút chỉång trçnh Prolog sàõp xãúp nhanh
mäüt danh sạch cạc säú â cho theo thỉï tỉû tàng dáưn.
17. Âc hiãøu chỉång trçnh sau âáy räưi dỉûng lải thût toạn :
/* Missionarys & Cannibals */
/* Trạnh vng làûp */
lNotExist(_,[]).
lNotExist(X,[T|Q]) :-
X\==T, lNotExist(X,Q).
116 Lỏỷp trỗnh lọgich trong Prolog
/* Kióứm tra tờnh hồỹp lyù cuớa traỷng thaùi */
valid(MG,CG,MD,CD) :-
MG>=0, CG>=0, MD>=0, CD>=0, MG=0, MD>=CD.
valid(MG,CG,MD,CD) :-
MG>=0, CG>=0, MD>=0, CD>=0, MG>=CG, MD=0.
valid(MG,CG,MD,CD) :-
MG>=0, CG>=0, MD>=0, CD>=0, MG>=CG, MD>=CD.
/* Xỏy dổỷng cung vaỡ kióứm tra */
sail(1,0). sail(0,1). sail(1,1). sail(2,0). sail(0,2).
arc([left,MGi,CGi,MDi,CDi],[droite,MGf,CGf,MDf,CDf]) :-

sail(Mis,Can),
MGf is MGi-Mis, MDf is MDi+Mis,
CGf is CGi-Can, CDf is CDi+Can,
valid(MGf,CGf,MDf,CDf).
arc([right,MGi,CGi,MDi,CDi],[left,MGf,CGf,MDf,CDf]) :-
sail(Mis,Can),
MGf is MGi+Mis, MDf is MDi-Mis,
CGf is CGi+Can, CDf is CDi-Can,
valid(MGf,CGf,MDf,CDf).
/* Pheùp õóỷ quy */
cross(A,A,[A],Non).
cross(X,Y,Ch,Non) :-
arc(X,A), lNotExist(A,Non),
cross(A,Y,ChAY,[A|Non]), Ch=[X|ChAY].
/* i qua */
traverse(X,Y,Ch) :-
cross(X,Y,Ch,[X]).



CHặNG 5
Kyợ thuỏỷt lỏỷp trỗnh Prolog

I. Nhaùt cừt
I.1. Khaùi nióỷm nhaùt cừt
Nhổ õaợ thỏỳy, mọỹt trỗnh Prolog õổồỹc thổỷc hióỷn nhồỡ caùc móỷnh õóử vaỡ caùc
õờch. Sau õỏy ta seợ xeùt mọỹt kyợ thuỏỷt khaùc cuớa Prolog cho pheùp ngn chỷn sổỷ
quay lui laỡ nhaùt cừt (cut).
Prolog tổỷ õọỹng quay lui khi cỏửn tỗm mọỹt tỗm kióỳm mọỹt móỷnh õóử khaùc õóứ
thoaớ maợn õờch. ióửu naỡy rỏỳt coù ờch õọỳi vồùi ngổồỡi lỏỷp trỗnh khi cỏửn sổớ duỷng

nhióửu phổồng aùn giaới quyóỳt vỏỳn õóử . Tuy nhión, nóỳu khọng kióứm soaùt tọỳt quaù
trỗnh naỡy, vióỷc quay lui seợ trồớ nón keùm hióỷu quaớ. Vỗ vỏỷy, Prolog sổớ duỷng kyợ
thuỏỷt nhaùt cừt kióứm soaùt quay lui, hay cỏỳm quay lui, õóứ khừc phuỷc khióỳm
khuyóỳt naỡy.
Trong vờ duỷ sau õỏy, mọỹt chổồng trỗnh Prolog sổớ duỷng kyợ thuỏỷt quay lui
keùm hióỷu quaớ. Ta cỏửn xaùc õởnh caùc vở trờ maỡ tổỡ õoù chổồng trỗnh bừt õỏửu quaù
trỗnh quay lui. Ta xeùt haỡm bỏỷc thang
Ta coù ba quy từc xaùc õởnh quan hóỷ giổợa hai truỷc X vaỡ Y nhổ sau :
1. Nóỳu X < 3 thỗ Y = 0
2. Nóỳu X 3 vaỡ X < 6 thỗ Y = 2
3. Nóỳu X 6 thỗ Y = 4
Ta vióỳt thaỡnh quan hóỷ nhở phỏn f( X, Y ) trong Prolog nhổ sau :
f( X, 0) :- X < 3. % luỏỷt 1
f( X, 2) :- 3 =< X, X < 6. % luỏỷt 2
f( X, 4) :- 6 =< X. % luỏỷt 3
117
118 Láûp trçnh lägich trong Prolog
+ + +++++++
3 6 X
Y

-
-
4 -
-
2 -
-

Hçnh I.1.Hm báûc thang cọ hai báûc.
Khi chảy chỉång trçnh, gi sỉí ràòng biãún X ca hm f( X, Y ) â âỉåüc nháûn

mäüt giạ trë säú âãø cọ thãø thỉûc hiãûn phẹp so sạnh trong thán hm. Tỉì âáy, xy
ra hai kh nàng sỉí dủng k thût nhạt càõt nhỉ sau :
I.2. K thût sỉí dủng nhạt càõt
I.2.1. K thût nhạt càõt thỉï nháút
Gi sỉí ta âàût ra cáu hi :
?- f( 1, Y ), 2 < Y.
Lục ny, Y nháûn giạ trë 0, âêch thỉï hai tråí thnh :
2 < 0
v gáy ra kãút qu No (tháút bải) cho c danh sạch cạc âêch cn lải, vç Prolog
cn tiãúp tủc tiãún hnh thãm hai quạ trçnh quay lui vä êch khạc :
f( 1, Y), 2 < Y.
Lût1 Lût2 Lût 3
Y = 0 Y = 2 Y = 4
Nhạt càõt Tháút bải Tháút bải
Tháút bải
1 < 3, 2 < 0
3 ≤ 1, 1 < 6, 2 < 2
2 < 0
6 ≤ 1, 2 < 4

Hçnh I.2. Tải vë trê
«
Nhạt càõt
»
, cạc lût 2 v 3 â biãút trỉåïc tháút bải.
Kyợ thuỏỷt lỏỷp trỗnh Prolog

119

Caớ ba luỏỷt õởnh nghộa quan hóỷ f coù tờnh chỏỳt loaỷi trổỡ lỏựn nhau, chố coù duy

nhỏỳt mọỹt trong chuùng laỡ coù thóứ thaỡnh cọng. Ngổồỡi lỏỷp trỗnh bióỳt õióửu naỡy
nhổng Prolog laỷi khọng bióỳt, cho nón cổù tióỳp tuỷc aùp duỷng tỏỳt caớ caùc luỏỷt mỷc
duỡ õi õóỳn thỏỳt baỷi. Trong vờ duỷ trón, luỏỷt 1 õổồỹc aùp duỷng taỷi vở trờ ôNhaùt
cừtằ vaỡ gỏy ra thỏỳt baỷi. óứ traùnh sổỷ quay lui khọng cỏửn thióỳt bừt õỏửu tổỡ vở
trờ naỡy, chuùng ta cỏửn baùo cho Prolog bióỳt mọỹt caùch tổồỡng minh, bũng caùch sổớ
duỷng mọỹt nhaùt cừt, kyù hióỷu bồới mọỹt dỏỳu chỏỳm than ô!ằ thổỷc chỏỳt laỡ mọỹt õờch
giaớ (pseudo goal) õổồỹc cheỡn vaỡo giổợa caùc õờch thỏỷt khaùc. Chổồng trỗnh haỡm
bỏỷc thang õổồỹc vióỳt laỷi nhổ sau :
f( X, 0) :- X < 3, !. % luỏỷt 1
f( X, 2) :-
3 =< X, X < 6, !. % luỏỷt 2
f( X, 4) :-
6 =< X. % luỏỷt 3
Nhaùt cừt ! seợ cỏỳm moỹi quaù trỗnh quay lui tổỡ vở trờ xuỏỳt hióỷn cuớa noù trong
chổồng trỗnh. Nóỳu bỏy giồỡ ta yóu cỏửu thổỷc hióỷn õờch :
?- f( 1, Y ), 2 < Y.
Prolog chố thổỷc hióỷn nhaùnh traùi nhỏỳt ổùng vồùi luỏỷt 1 trong hỗnh trón, traớ vóử
kóỳt quaớ thỏỳt baỷi vỗ xaớy ra 2 < 0 maỡ khọng tióỳp tuỷc quay lui thổỷc hióỷn caùc
nhaùnh tổồng ổùng vồùi luỏỷt 2 vaỡ 3, do õaợ gỷp nhaùt cừt !. Chổồng trỗnh mồùi sổớ
duỷng nhaùt cừt chaỷy hióỷu quaớ hồn chổồng trỗnh cuợ. Khi xaớy ra thỏỳt baỷi,
Prolog seợ nhanh choùng dổỡng, maỡ khọng mỏỳt thồỡi gian õóứ thổỷc hióỷn nhổợng
vióỷc vọ ờch khaùc. Sổớ duỷng nhaùt cừt trong mọỹt chổồng trỗnh laỡm thay õọứi
nghộa thuớ tuỷc nhổng khọng laỡm thay õọứi nghộa khai baùo. Tuy nhión sau õỏy
ta seợ thỏỳy rũng nhaùt cừt coù thóứ laỡm mỏỳt õi nghộa khai baùo.
I.2.2. Kyợ thuỏỷt nhaùt cừt thổù hai
Giaớ sổớ bỏy giồỡ ta goỹi thổỷc hióỷn õờch :
?- f( 7, Y ).
Y=4
Yes
Quaù trỗnh thổỷc hióỷn õổồỹc mọ taớ nhổ sau : trổồùc khi nhỏỷn õổồỹc kóỳt quaớ,

vóử nguyón từc, Prolog phaới sổớ duỷng caớ ba luỏỷt õóứ coù quaù trỗnh xoaù õờch.

×