Professional Documents
Culture Documents
.
LÅÌI NOÏI ÂÁÖU
Cuäún saïch naìy nhàòm cung cáúp cå såí lyï thuyãút vaì caïc phæång phaïp
láûp trçnh cå baín nháút cuía män hoüc «Láûp trçnh lägich» (Programming in Logic).
Ngæåìi âoüc seî âæåüc laìm quen våïi mäüt säú kyî thuáût láûp trçnh lägich âæåüc æïng duûng
tæång âäúi phäø biãún vaì chuí yãúu trong lénh væûc trê tuãû nhán taûo (Artificial
Intelligence) nhæ cäng nghãû xæí lyï tri thæïc, maïy hoüc, hãû chuyãn gia, xæí lyï ngän
ngæî tæû nhiãn, troì chåi, v.v...
Cuäún saïch gäöm nàm chæång vaì phuû luûc nhæ sau :
− Chæång 1 giåïi thiãûu ngän ngæî láûp trçnh Prolog lägich dæûa trãn lägich
Horn (Horn logic). Ngæåìi âoüc laìm quen våïi caïc kiãøu dæî liãûu cuía Prolog,
khaïi niãûm vãö luáût, sæû kiãûn vaì viãút caïc chæång trçnh Prolog âån giaín.
− Chæång 2 trçnh baìy caïc mæïc nghéa khaïc nhau cuía mäüt chæång trçnh
Prolog : nghéa lägich, nghéa khai baïo vaì nghéa thuí tuûc, caïch Prolog traí
låìi caïc cáu hoíi, caïch laìm thoaí maîn âêch.
− Chæång 3 trçnh baìy caïc pheïp toaïn säú hoüc, pheïp so saïnh vaì âënh nghéa
haìm sæí duûng pheïp âãû quy trong Prolog.
− Chæång 4 trçnh baìy cáúu truïc danh saïch vaì caïc pheïp xæí lyï cå baín trãn
danh saïch cuía Prolog.
− Chæång 5 trçnh baìy kyî thuáût láûp trçnh náng cao våïi Prolog.
− Pháön phuû luûc giåïi thiãûu ngän ngæî láûp trçnh SWI-Prolog, hæåïng dáùn
caïch caìi âàût sæí duûng pháön mãöm naìy vaì mäüt säú chæång trçnh vê duû tiãu
biãøu viãút trong SWI Prolog.
Cuäún saïch naìy duìng laìm giaïo trçnh cho sinh viãn ngaình Tin hoüc vaì caïc
âäüc giaí muäún tçm hiãøu thãm vãö kyî thuáût láûp trçnh cho lénh væûc trê tuãû nhán taûo.
Trong quaï trçnh biãn soaûn, taïc giaí âaî nháûn âæåüc tæì caïc baûn âäöng nghiãûp
nhiãöu âoïng goïp bäø êch vãö màût chuyãn män, nhæîng âäüng viãn khêch lãû vãö màût
tinh tháön, sæû giuïp âåî vãö biãn táûp âãø cuäún saïch âæåüc ra âåìi. Taïc giaí xin âæåüc
baìy toí loìng biãút ån sáu sàõc. Taïc giaí cuîng chán thaình caím ån moüi yï kiãún phã
bçnh âoïng goïp cuía baûn âoüc gáön xa vãö näüi dung cuía cuäún saïch naìy.
i
II.3. Nghéa lägich cuía caïc mãûnh âãö.................................................. 35
II.4. Nghéa thuí tuûc cuía Prolog ......................................................... 37
II.5. Täø håüp caïc yãúu täú khai baïo vaì thuí tuûc ..................................... 47
III. VÊ DUÛ : CON KHÈ VAÌ QUAÍ CHUÄÚI ....................................... 48
III.1. Phaït biãøu baìi toaïn .................................................................... 48
III.2. Giaíi baìi toaïn våïi Prolog............................................................ 49
III.3. Sàõp âàût thæï tæû caïc mãûnh âãö vaì caïc âêch .................................. 54
III.3.1. Nguy cå gàûp caïc voìng làûp vä haûn ............................................. 54
III.3.2. Thay âäøi thæï tæû mãûnh âãö vaì âêch trong chæång trçnh ............. 56
CHÆÅNG 3 CAÏC PHEÏP TOAÏN VAÌ SÄÚ HOÜC .......................................65
I. SÄÚ HOÜC .................................................................................... 65
I.1. Caïc pheïp toaïn säú hoüc ................................................................ 65
I.2. Biãøu thæïc säú hoüc ....................................................................... 65
I.3. Âënh nghéa caïc pheïp toaïn trong Prolog ................................... 68
II. CAÏC PHEÏP SO SAÏNH CUÍA PROLOG .................................... 73
II.1. Caïc pheïp so saïnh säú hoüc ........................................................... 73
II.2. Caïc pheïp so saïnh haûng............................................................. 75
II.3. Vë tæì xaïc âënh kiãøu ................................................................... 77
II.4. Mäüt säú vë tæì xæí lyï haûng ............................................................ 77
III. ÂËNH NGHÉA HAÌM ................................................................. 79
III.1. Âënh nghéa haìm sæí duûng âãû quy.............................................. 79
III.2. Täúi æu pheïp âãû quy................................................................... 87
III.3. Mäüt säú vê duû khaïc vãö âãû quy..................................................... 88
III.3.1. Tçm âæåìng âi trong mäüt âäö thë coï âënh hæåïng ........................ 88
III.3.2. Tênh âäüü daìi âæåìng âi trong mäüt âäö thë .................................... 89
III.3.3. Tênh gáön âuïng caïc chuäùi .......................................................... 90
CHÆÅNG 4 CÁÚU TRUÏC DANH SAÏCH.................................................95
I. BIÃØU DIÃÙN CÁÚU TRUÏC DANH SAÏCH .................................. 95
II. MÄÜT SÄÚ VË TÆÌ XÆÍ LYÏ DANH SAÏCH CUÍA PROLOG ........... 98
III. CAÏC THAO TAÏC CÅ BAÍN TRÃN DANH SAÏCH .................... 99
III.1. Xáy dæûng laûi mäüt säú vë tæì coï sàôn ............................................. 99
III.2. Hoaïn vë ................................................................................... 107
ii
III.3. Mäüt säú vê duû vãö danh saïch...................................................... 109
CHÆÅNG 5 KYÎ THUÁÛT LÁÛP TRÇNH PROLOG ..............................117
I. NHAÏT CÀÕT ............................................................................. 117
I.1. Khaïi niãûm nhaït càõt ................................................................ 117
I.2. Kyî thuáût sæí duûng nhaït càõt ..................................................... 118
I.3. Pheïp phuí âënh ........................................................................ 126
II. SÆÍ DUÛNG CAÏC CÁÚU TRUÏC .................................................. 131
II.1. Truy cáûp thäng tin cáúu truïc tæì mäüt cå såí dæî liãûu .................. 132
II.2. Træìu tæåüng hoaï dæî liãûu .......................................................... 136
II.3. Mä phoíng ätämat hæîu haûn ..................................................... 138
II.4. Vê duû : láûp kãú hoaûch âi du lëch bàòng maïy bay ....................... 144
II.5. Baìi toaïn taïm quán háûu .......................................................... 150
III. QUAÏ TRÇNH VAÌO-RA VAÌ LAÌM VIÃÛC VÅÏI TÃÛP .................. 163
III.1. Khaïi niãûm ............................................................................... 163
III.2. Laìm viãûc våïi caïc tãûp ................................................................ 164
III.3. ÆÏng duûng chãú âäü laìm viãûc våïi caïc tãûp .................................... 172
PHUÛ LUÛC A MÄÜT SÄÚ CHÆÅNG TRÇNH PROLOG..........................187
PHUÛ LUÛC B HÆÅÏNG DÁÙN SÆÍ DUÛNG SWI-PROLOG .....................194
I. GIÅÏI THIÃUU SWI-PROLOG............................................... 194
II. LAIM VIÃUC VÅÏI SWI-PROLOG......................................... 195
II.1. Âàût cáu hoíi .............................................................................. 195
II.2. Chaûy trçnh demo..................................................................... 196
II.3. Chaûy trçnh demo XPCE ......................................................... 197
II.4. Caïc lãûnh âån (Menu commands)............................................ 198
II.5. Soaûn thaío chæång trçnh.......................................................... 200
III. MÄÜT SÄÚ LÃÛNH SWI-PROLOG THÄNG DUÛNG.................. 201
TAÌI LIÃÛU THAM KHAÍO ............................................................................ 203
iii
CHÆÅNG 1
P rolog laì ngän ngæî âæåüc sæí duûng phäø biãún nháút trong doìng caïc ngän
ngæî láûp trçnh lägich (Prolog coï nghéa laì PROgramming in LOGic).
Ngän ngæî Prolog do giaïo sæ ngæåìi Phaïp Alain Colmerauer vaì nhoïm
nghiãn cæïu cuía äng âãö xuáút láön âáöu tiãn taûi træåìng Âaûi hoüc Marseille âáöu
nhæîng nàm 1970. Âãún nàm 1980, Prolog nhanh choïng âæåüc aïp duûng räüng raîi
åí cháu Áu, âæåüc ngæåìi Nháût choün laìm ngän ngæî phaït triãøn doìng maïy tênh
thãú hãû 5. Prolog âaî âæåüc caìi âàût trãn caïc maïy vi tênh Apple II, IBM-PC,
Macintosh.
Prolog coìn âæåüc goüi laì ngän ngæî láûp trçnh kyï hiãûu (symbolic programming)
tæång tæû caïc ngän ngæî láûp trçnh haìm (functional programming), hay láûp trçnh phi
säú (non-numerical programming). Prolog ráút thêch håüp âãø giaíi quyãút caïc baìi toaïn
liãn quan âãún caïc âäúi tæåüng (object) vaì mäúi quan hãû (relation) giæîa chuïng.
Prolog âæåüc sæí duûng phäø biãún trong lénh væûc trê tuãû nhán taûo. Nguyãn lyï
láûp trçnh lägich dæûa trãn caïc mãûnh âãö Horn (Horn logêc). Mäüt mãûnh âãö Horn
biãùu diãùn mäüt sæû kiãûn hay mäüt sæû viãûc naìo âoï laì âuïng hoàûc khäng âuïng, xaíy
ra hoàûc khäng xaíy ra (coï hoàûc khäng coï, v.v...).
1
2 Láûp trçnh logic trong Prolog
Vê duû I.1 : Sau âáy laì mäüt säú mãûnh âãö Horn :
1. Nãúu mäüt ngæåìi giaì maì (vaì) khän ngoan thç ngæåìi âoï haûnh phuïc.
2. Jim laì ngæåìi haûnh phuïc.
3. Nãúu X laì cha meû cuía Y vaì Y laì cha meû cuía Z thç X laì äng cuía Z.
4. Tom laì äng cuía Pat.
5. Táút caí moüi ngæåìi âãöu chãút (hoàûc Nãúu ai laì ngæåìi thç ai âoï phaíi chãút).
6. Socrat laì ngæåìi.
Trong caïc mãûnh âãö Horn åí trãn, caïc mãûnh âãö 1, 3, 5 âæåüc goüi laì caïc luáût
(rule), caïc mãûnh âãö coìn laûi âæåüc goüi laì caïc sæû kiãûn (fact). Mäüt chæång trçnh
lägich coï thãø âæåüc xem nhæ laì mäüt cå såí dæî liãûu gäöm caïc mãûnh âãö Horn, hoàûc
daûng luáût, hoàûc daûng sæû kiãûn, chàóng haûn nhæ táút caí caïc sæû kiãûn vaì luáût tæì 1
âãún 6 åí trãn. Ngæåìi sæí duûng (NSD) goüi chaûy mäüt chæång trçnh lägich bàòng
caïch âàût cáu hoíi (query/ question) truy váún trãn cå såí dæî liãûu naìy, chàóng
haûn cáu hoíi :
Socrat coï chãút khäng ?
(tæång âæång khàóng âënh Socrat chãút âuïng hay sai ?)
Mäüt hãû thäúng lägich seî thæûc hiãûn chæång trçnh theo caïch «suy luáûn»-tçm
kiãúm dæûa trãn väún «hiãøu biãút» âaî coï laì chæång trçnh - cå såí dæî liãûu, âãø minh
chæïng cáu hoíi laì mäüt khàóng âënh, laì âuïng (Yes) hoàûc sai (No). Våïi cáu hoíi
trãn, hãû thäúng tçm kiãúm trong cå såí dæî liãûu khàóng âënh Socrat chãút vaì «tçm
tháúy» luáût 5 thoaí maîn (vãú thç). Váûn duûng luáût 5, hãû thäúng nháûn âæåüc Socrat
laì ngæåìi (vãú nãúu) chênh laì sæû kiãûn 5. Tæì âoï, cáu traí låìi seî laì :
Yes
coï nghéa Socrat chãút laì âuïng.
Mäùi nguyãn tæí (noïi goün) biãøu diãùn mäüt quan hãû giæîa caïc haûng (term).
Nhæ váûy, haûng vaì quan hãû giæîa caïc haûng taûo thaình mãûnh âãö.
Haûng âæåüc xem laì nhæîng âäúi tæåüng “dæî liãûu” trong mäüt trçnh Prolog.
Haûng coï thãø laì haûng så cáúp (elementary term) gäöm hàòng (constant), biãún
(variable) vaì caïc haûng phæïc håüp (compound term).
Caïc haûng phæïc håüp biãøu diãùn caïc âäúi tæåüng phæïc taûp cuía baìi toaïn cáön giaíi
quyãút thuäüc lénh væûc âang xeït. Haûng phæïc håüp laì mäüt haìm tæí (functor) coï
chæïa caïc âäúi (argument), coï daûng
Mãûnh âãö coï thãø laì mäüt sæû kiãûn, mäüt luáût (hay quy tàõc), hay mäüt cáu hoíi.
Prolog quy æåïc viãút sau mäùi mãûnh âãö mäüt dáúu cháúm âãø kãút thuïc nhæ sau :
• Sæû kiãûn : < ... >. (tæång æïng våïi luáût < ... > :- true. )
• Luáût : < ... > :- < ... >.
• Cáu hoíi ?- < ... >. (åí chãú âäü tæång taïc coï dáúu nhàõc lãûnh)
hàòng biãún
Caïc kiãøu dæî liãûu Prolog âæåüc xáy dæûng tæì caïc kyï tæû ASCII :
• Caïc chæî caïi in hoa A, B, ..., Z vaì chæî caïi in thæåìng a, b, ..., z.
• Caïc chæî säú 0, 1, ..., 9.
• Caïc kyï tæû âàûc biãût, chàóng haûn + − ∗ / < > = : . & _ ∼.
II.2. Biãún
Tãn biãún laì mäüt chuäùi kyï tæû gäöm chæî caïi, chæî säú, bàõt âáöu båíi chæî hoa
hoàûc dáúu gaûch dæåïi doìng :
X, Y, A
Result, List_of_members
_x23, _X, _, ...
pam tom
parent
bob liz
jim
(a) (b)
Hçnh III.1.Cáy gia hãû.
Måí âáöu vãö ngän ngæî Prolog 7
Trong cáy gia hãû (a), caïc nuït chè ngæåìi, coìn caïc muîi tãn chè quan hãû cha
meû cuía (parent of). Sæû kiãûn Tom laì cha meû cuía Bob âæåüc viãút thaình mäüt vë
tæì Prolog nhæ sau (chuï yï mãûnh âãö âæåüc kãút thuïc båíi mäüt dáúu cháúm) :
parent(tom, bob). % Chuï yï khäng coï dáúu caïch træåïc dáúu måí ngoàûc
ÅÍ âáy, vë tæì parent coï hai âäúi laì tom vaì bob. Ngæåìi ta coï thãø biãøu diãùn vë
tæì naìy båíi mäüt cáy nhæ trong Hçnh III.1 (b) : nuït gäúc laì tãn vë tæì, caïc nuït laï laï
caïc âäúi.
Tæì cáy gia hãû trãn âáy, coï thãø tiãúp tuûc viãút caïc vë tæì khaïc âãø nháûn âæåüc
mäüt chæång trçnh Prolog gäöm 6 vë tæì nhæ sau :
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
parent(bob, ann).
parent(bob, pat).
parent(pat, jim).
Sau khi hãû thäúng Prolog nháûn âæåüc chæång trçnh naìy, thæûc cháút laì mäüt cå
såí dæî liãûu, ngæåìi ta coï thãø âàût ra caïc cáu hoíi liãn quan âãún quan hãû parent.
Vê duû cáu hoíi Bob coï phaíi laì cha meû cuía Pat âæåüc goî vaìo trong hãû thäúng âäúi
thoaûi Prolog (dáúu nhàõc ?-_) nhæ sau :
?- parent(bob, pat).
Sau khi tçm tháúy sæû kiãûn naìy trong chæång trçnh, Prolog traí låìi :
Yes
Ta tiãúp tuûc âàût cáu hoíi khaïc :
?- parent(liz, pat).
No
Båíi vç Prolog khäng tçm tháúy sæû kiãûn Liz laì ngæåìi meû cuía Pat trong
chæång trçnh. Tæång tæû, Prolog traí låìi No cho sæû kiãûn :
?- parent(tom, ben).
Vç tãn ben chæa âæåüc âæa vaìo trong chæång trçnh. Ta coï thãø tiãúp tuûc âàût
ra caïc cáu hoíi thuï vë khaïc. Chàóng haûn, ai laì cha (hay meû) cuía Liz ?
?- parent(X, liz).
Láön naìy, Prolog khäng traí låìi Yes hoàûc No, maì âæa ra mäüt giaï trë cuía X
laìm thoaí maîn cáu hoíi trãn âáy :
8 Láûp trçnh logic trong Prolog
X = tom
Âãø biãút âæåüc ai laì con cuía Bob, ta chè cáön viãút :
?- parent(bob, X).
Våïi cáu hoíi naìy, Prolog seî coï hai cáu traí låìi, âáöu tiãn laì :
X = ann ->;
Âãø biãút âæåüc cáu traí låìi tiãúp theo, trong háöu hãút caïc caìi âàût cuía Prolog,
NSD phaíi goî vaìo mäüt dáúu cháúm pháøy (;) sau -> (Arity Prolog) :
X = pat
Nãúu âaî hãút phæång aïn traí låìi maì váùn tiãúp tuûc yãu cáöu (;), Prolog traí låìi
No.
NSD coï thãø âàût caïc cáu hoíi täøng quaït hån, chàóng haûn : ai laì cha meû cuía
ai ? Noïi caïch khaïc, cáön tçm X vaì Y sao cho X laì cha meû cuía Y. Ta viãút nhæ
sau :
?- parent(X, Y).
Sau khi hiãøn thë cáu traí låìi âáöu tiãn, Prolog seî láön læåüt tçm kiãúm nhæîng
càûp cha meû − con thoaí maîn vaì láön læåüt hiãøn thë kãút quaí nãúu chæìng naìo NSD
coìn yãu cáöu cho âãún khi khäng coìn kãút quaí låìi giaíi naìo næîa (kãút thuïc båíi
Yes) :
X = pam
Y = bob ->;
X = tom
Y = bob ->;
X = tom
Y = liz ->;
X = bob
Y = ann ->;
X = bob
Y = pat ->;
X = pat
Y = jim
Yes
Tuyì theo caìi âàût Prolog, NSD coï thãø goî vaìo mäüt dáúu cháúm (.) hoàûc Enter
âãø cháúm dæït giæîa chæìng luäöng traí låìi.
Måí âáöu vãö ngän ngæî Prolog 9
Ta coï thãø tiãúp tuûc âæa ra nhæîng cáu hoíi phæïc taûp hån khaïc, chàóng haûn ai
laì äng (baì) cuía Jim ? Thæûc tãú, quan hãû äng − baì (grandparent) chæa âæåüc
âënh nghéa, cáön phaíi phán taïch cáu hoíi naìy thaình hai pháön så cáúp hån :
1. Ai laì cha (meû) cuía Jim ? Giaí sæí coï tãn laì Y.
2. Ai laì cha (meû) cuía Y ? Giaí sæí coï tãn laì X.
X
parent
Y grandparent
parent
jim
Hçnh III.2. Quan hãû äng baì âæåüc håüp thaình tæì hai quan hãû cha meû.
X = bob
Y = pat ->;
No
Mäüt cáu hoíi khaïc coï thãø nhæ sau : Ann vaì Pat coï cuìng ngæåìi äng khäng ?
nghéa laì ta diãùn âaût thaình hai giai âoaûn :
1. Tçm X laì cha meû cuía Ann.
2. X tçm tháúy coï cuìng laì cha meû cuía Pat khäng ?
Cáu hoíi vaì traí låìi trong Prolog nhæ sau :
?- parent(X, ann), parent(X, pat).
X = bob
Trong Prolog, cáu hoíi coìn âæåüc goüi laì âêch (goal) cáön phải âæåüc thoaí maîn
(satisfy). Mäùi cáu hoíi âàût ra âäúi våïi cå såí dæî liãûu coï thãø tæång æïng våïi mäüt
hoàûc nhiãöu âêch. Chàóng haûn daîy caïc âêch :
parent(X, ann), parent(X, pat).
tæång æïng våïi cáu hoíi laì pheïp häüi (conjunction) cuía 2 mãûnh âãö :
X laì mäüt cha meû cuía Ann, vaì
X laì mäüt cha meû cuía Pat.
Nãúu cáu traí låìi laì Yes, thç coï nghéa âêch âaî âæåüc thoaí maîn, hay âaî thaình
cäng. Trong træåìng håüp ngæåüc laûi, cáu traí låìi laì No, coï nghéa âêch khäng âæåüc
thoaí maîn, hay âaî tháút baûi.
Nãúu coï nhiãöu cáu traí låìi cho mäüt cáu hoíi, Prolog seî âæa ra cáu traí låìi âáöu
tiãn vaì chåì yãu cáöu cuía NSD tiãúp tuûc.
• pháön bãn phaíi (RHS: Right Hand Side) chè âiãöu kiãûn, coìn âæåüc goüi laì
thán (body) cuía luáût, vaì
• pháön bãn traïi (LH: Left Hand Side S) chè kãút luáûn, coìn âæåüc goüi laì âáöu
(head) cuía luáût.
12 Láûp trçnh logic trong Prolog
Nãúu âiãöu kiãûn parent(X, Y) laì âuïng, thç child(Y, X) cuîng âuïng vaì laì háûu
quaí lägich cuía pheïp suy luáûn (inference).
âáöu thán
Cáu hoíi sau âáy giaíi thêch caïch Prolog sæí duûng caïc luáût : Liz coï phaíi laì
con cuía Tom khäng ?
?- child(liz, tom)
Thæûc tãú, trong chæång trçnh khäng coï sæû kiãûn naìo liãn quan âãún con, maì
ta phaíi tçm caïch aïp duûng caïc luáût. Luáût trãn âáy åí daûng täøng quaït våïi caïc âäúi
tæåüng X vaì Y báút kyì, maì ta laûi cáön caïc âäúi tæåüng cuû thãø liz vaì tom.
Ta cáön sæí duûng pheïp thãú (substitution) bàòng caïch gaïn giaï trë liz cho biãún
Y vaì tom cho X. Ngæåìi ta noïi ràòng caïc biãún X vaì Y âaî âæåüc raìng buäüc
(bound) :
X = tom
vaì
Y = liz
Luïc naìy, pháön âiãöu kiãûn coï giaï trë parent(tom, liz) vaì tråí thaình âêch con
(sub-goal) âãø Prolog thay thãú cho âêch child(liz, tom). Tuy nhiãn, âêch naìy
thoaí maîn vaì coï giaï trë Yes vç chênh laì sæû kiãûn âaî thiãút láûp trong chæång
trçnh.
Sau âáy, ta tiãúp tuûc bäø sung caïc quan hãû måïi. Quan hãû meû mother âæåüc
âënh nghéa nhæ sau (chuï yï dáúu pháøy chè pheïp häüi hay pheïp vaì lägich) :
mother(X, Y) :- parent(X, Y), woman(X).
âæåüc hiãøu laì :
Våïi moüi X vaì Y, X laì meû cuía Y nãúu
X laì cha (hay meû) cuía Y vaì X laì næî.
Âäö thë sau âáy minh hoaû viãûc âënh nghéa caïc quan hãû child, mother vaì
grandparent sæí duûng mäüt quan hãû khaïc :
Trong âäö thë, ngæåìi ta quy æåïc ràòng : caïc nuït tæång æïng våïi caïc âäúi tæåüng
(laì caïc âäúi cuía mäüt quan hãû). Caïc cung näúi caïc nuït tæång æïng våïi caïc quan hãû
Måí âáöu vãö ngän ngæî Prolog 13
nhë phán, âæåüc âënh hæåïng tæì âäúi thæï nháút âãún âäúi thæï hai cuía quan hãû.
Mäüt quan hãû âån âæåüc biãøu diãùn båíi tãn quan hãû tæång æïng våïi nhaîn cuía
âäúi tæåüng âoï. Caïc quan hãû cáön âënh nghéa âæåüc biãøu diãùn båíi caïc cung coï neït
âæït. Mäùi âäö thë âæåüc giaíi thêch nhæ sau : nãúu caïc quan hãû âæåüc chè båíi caïc
cung coï neït liãön âæåüc thoaí maîn, thç quan hãû biãøu diãùn båíi cung coï neït âæït
cuîng âæåüc thoaí maîn.
woman
X X X
parent child parent mother parent
Y Y Y grandparent
parent
Z
Hçnh III.3. Âënh nghéa quan hãû con, meû vaì äng baì sæí duûng mäüt quan hãû khaïc.
Nhæ váûy, quan hãû äng−baì grandparent âæåüc viãút nhæ sau :
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
Âãø thuáûn tiãûn cho viãûc âoüc chæång trçnh Prolog, ta coï thãø viãút mäüt luáût
trãn nhiãöu doìng, doìng âáöu tiãn laì pháön âáöu cuía luáût, caïc doìng tiãúp theo laì
pháön thán cuía luáût, mäùi âêch trãn mäüt doìng phán biãût. Báy giåì quan hãû
grandparent âæåüc viãút laûi nhæ sau :
grandparent(X, Z) :-
parent(X, Y),
parent(Y, Z).
Ta tiãúp tuûc âënh nghéa quan hãû chë em gaïi sister nhæ sau :
sister(X, Y) :- Våïi moüi X vaì Y, X laì mäüt chë (em) gaïi cuía Y nãúu
parent(Z, X), (1) X vaì Y coï cuìng cha (cuìng meû), vaì
parent(Z, Y),
woman(X). (2) X laì næî .
Z
parent parent
woman X Y
sister
Hçnh III.4. Âënh nghéa quan hãû chë (em) gaïi.
14 Láûp trçnh logic trong Prolog
Chuï yï caïch giaíi thêch âiãöu kiãûn X vaì Y coï cuìng cha meû : mäüt Z naìo âoï
phaíi laì mäüt cha meû cuía X, vaì cuîng Z âoï phaíi laì mäüt cha meû cuía Y.
Hay noïi mäüt caïch khaïc laì : Z1 laì mäüt cha meû cuía X, Z2 laì mäüt cha meû cuía
Y, vaì Z1 âäöng nháút våïi Z2.
An laì næî, Ann vaì Pat cuìng cha meû nãn Ann laì chë em gaïi cuía Pat, ta coï :
?- sister(ann, pat).
Yes
Ta cuîng coï thãø hoíi ai laì chë em gaïi cuía Pat nhæ sau :
?- sister(X, pat).
Prolog seî láön læåüt âæa ra hai cáu traí låìi :
X = ann ->;
X = pat ->.
Yes
Váûy thç Pat laûi laì em gaïi cuía chênh mçnh ?! Âiãöu naìy sai vç ta chæa giaíi
thêch roî trong âënh nghéa chë em gaïi. Nãúu chè dæûa vaìo âënh nghéa trãn âáy
thç cáu traí låìi cuía Prolog laì hoaìn toaìn håüp lyï. Prolog suy luáûn ràòng X vaì Y coï
thãø âäöng nháút våïi nhau, mäùi ngæåìi âaìn baì coï cuìng cha meû seî laì em gaïi cuía
chênh mçnh. Ta cáön sæía laûi âënh nghéa bàòng caïch thãm vaìo âiãöu kiãûn X vaì Y
khaïc nhau. Nhæ seî tháúy sau naìy, Prolog coï nhiãöu caïch âãø giaíi quyãút, tuy
nhiãn luïc naìy ta giaí sæí ràòng quan hãû :
different(X, Y)
âaî âæåüc Prolog nháûn biãút vaì âæåüc thoaí maîn nãúu vaì chè nãúu X vaì Y khäng
bàòng nhau. Âënh nghéa chë (em) gaïi måïi nhæ sau :
sister(X, Y) :-
parent(Z, X),
parent(Z, Y),
woman(X).
different(X, Y).
Vê duû III.2 : Ta láúy laûi vê duû cäø âiãøn sæí duûng hai tiãn âãö sau âáy :
Táút caí moüi ngæåìi âãöu chãút.
Socrate laì mäüt ngæåìi.
Ta viãút trong Prolog nhæ sau :
mortal(X) :- man(X).
man(socrate).
Måí âáöu vãö ngän ngæî Prolog 15
Mäüt âënh lyï âæåüc suy luáûn mäüt caïch lägich tæì hai tiãn âãö naìy laì Socrate
phaíi chãút. Ta âàût caïc cáu hoíi nhæ sau :
?- mortal(socrate).
Yes
Vê duû III.3 :
Âãø chè Paul cuîng laì ngæåìi, coìn Bonzo laì con váût, ta viãút caïc sæû kiãûn :
man(paul).
animal(bonzo).
Con ngæåìi coï thãø noïi vaì khäng phaíi laì loaûi váût, ta viãút luáût :
speak(X) :- man(X), not(animal(bonzo)).
Ta âàût caïc cáu hoíi nhæ sau :
?- speak(bonzo).
No
?- speak(paul).
Yes
Vê duû III.4 :
Ta âaî xáy dæûng caïc sæû kiãûn vaì caïc luáût coï daûng vë tæì chæïa tham âäúi, sau
âáy, ta láúy mäüt vê duû khaïc vãö sæû kiãûn vaì luáût khäng chæïa tham âäúi :
'It is sunny'.
'It is summer'.
'It is hot' :-
'It is summer', 'It is sunny'.
'It is cold' :-
'It is winter', 'It is snowing'.
Tæì chæång trçnh trãn, ta coï thãø âàût cáu hoíi :
?- 'It is hot'.
Yes
Cáu traí låìi 'It is hot' laì âuïng vç âaî coï caïc sæû kiãûn 'It is sunny' vaì 'It is
summer' trong chæång trçnh. Coìn cáu hoíi « ?- 'It is cold.' » coï cáu traí låìi sai.
Ta noïi ràòng X laì mäüt täø tiãn giaïn tiãúp cuía Z nãúu täön taûi mäüt liãn hãû cha
meû (äng baì) giæîa X vaì Z :
X X
Z
(a) parent ancestor
parent
Y
(b)
Hçnh III.5. Quan hãû täø tiãn : (a) X laì täø tiãn træûc tiãúp cuía Z,
(b) X laì täø tiãn giaïn tiãúp cuía Z.
Trong cáy gia hãû åí Hçnh III.1, Tom laì täø tiãn træûc tiãúp cuía Liz, vaì täø tiãn
giaïn tiãúp cuía Pat. Ta âënh nghéa luáût 1 (täø tiãn træûc tiãúp) nhæ sau :
ancestor(X, Z) :- Våïi moüi X vaì Z,
parent(X, Z). X laì mäüt täø tiãn cuía Z nãúu
X laì cha meû cuía Z .
Âënh nghéa luáût 2 (täø tiãn giaïn tiãúp) phæïc taûp hån, trçnh Prolog tråí nãn
daìi doìng hån, mäùi khi caìng måí räüng mæïc täø tiãn háûu duãû nhæ chè ra trong
Hçnh III.6. Kãø caí luáût 1, ta coï quan hãû täø tiãn âæåüc âënh nghéa nhæ sau :
ancestor(X, Z) :- % luáût 1 âënh nghéa täø tiãn træûc tiãúp
parent(X, Z).
ancestor(X, Z) :- % luáût 2 : täø tiãn giaïn tiãúp laì äng baì (tam âaûi)
parent(X, Y),
parent(Y, Z).
ancestor(X, Z) :- % täø tiãn giaïn tiãúp laì cäú äng cäú baì (tæï âaûi)
parent(X, Y1),
parent(Y1, Y2),
parent(Y2, Z).
ancestor(X, Z) :- % nguî âaûi âäöng âæåìng
parent(X, Y1),
parent(Y1, Y2),
parent(Y2, Y3),
parent(Y3, Z).
...
Måí âáöu vãö ngän ngæî Prolog 17
X X X
parent parent
Y ancestor Y1 Y1
Hçnh III.6. Caïc càûp täø tiãn háûu duãû giaïn tiãúp åí caïc mæïc khaïc nhau.
Tuy nhiãn, täön taûi mäüt caïch âënh nghéa täø tiãn giaïn tiãúp åí mæïc báút kyì nhåì
pheïp âãû quy (recursive) nhæ sau :
ancestor(X, Z) :- Våïi moüi X vaì Z,
parent(X, Z). X laì mäüt täø tiãn cuía Z nãúu
ancestor(X, Z) :- täön taûi Y sao cho
parent(X, Y), (1) X laì cha meû cuía Y vaì
ancestor(Y, Z).
(2) Y laì mäüt täø tiãn cuía Z.
ancestor
parent
X Y ... Z
ancestor
Hçnh III.7.Daûng âãû quy cuía quan hãû täø tiãn (âæåüc quay ngang cho thuáûn tiãûn).
?- ancestor(pam, X).
X = jim ->;
X = ann ->;
X = pat ->;
X = bob
Yes
Trong Prolog, háöu hãút caïc chæång trçnh phæïc taûp âãöu sæí duûng âãû quy, âãû
quy laì mäüt khaí nàng maûnh cuía Prolog.
18 Láûp trçnh logic trong Prolog
Cho âãún luïc naìy, ta âaî âënh nghéa nhiãöu quan hãû khaïc nhau (parent,
woman, man, grandparent, child, sister, mother vaì ancestor). Ta tháúy mäùi quan
hãû chè tæång æïng våïi mäüt mãûnh âãö, tuy nhiãn, quan hãû ancestor laûi coï hai
mãûnh âãö.
Ngæåìi ta noïi ràòng nhæîng mãûnh âãö naìy liãn quan (concern) âãún quan hãû
ancestor. Trong træåìng håüp táút caí caïc mãûnh âãö âãöu liãn quan âãún mäüt quan
hãû, ngæåìi ta nháûn âæåüc mäüt thuí tuûc (procedure).
naìo âoï coï con nãúu täön taûi hai âäúi tæåüng sao cho mäüt âäúi tæåüng naìy laì cha cuía
âäúi tæåüng kia, thç ta coï thãø viãút :
someone_has_a_child :- parent(_, _).
Mãûnh âãö naìy tæång âæång våïi :
someone_has_a_child :- parent(X, Y).
nhæng hoaìn toaìn khaïc våïi :
someone_has_a_child :- parent(X, X).
Nãúu biãún nàûc danh xuáút hiãûn trong mäüt cáu hoíi, thç Prolog seî khäng hiãøn
thë giaï trë cuía biãún naìy trong kãút quaí traí vãö. Nãúu ta muäún tçm kiãúm nhæîng
ngæåìi coï con, maì khäng quan tám âãún tãn con laì gç, thç chè cáön viãút :
?- parent(X, _).
hoàûc tçm kiãúm nhæîng ngæåìi con, maì khäng quan tám âãún cha meû laì gç :
?- parent(_ , X).
Táöm væûc tæì væûng (lexical scope) cuía caïc biãún trong mäüt mãûnh âãö khäng
væåüt ra khoíi mãûnh âãö âoï. Coï nghéa laì nãúu, vê duû, biãún X15 xuáút hiãûn trong
hai mãûnh âãö khaïc nhau, thç seî tæång æïng våïi hai biãún phán biãût nhau. Trong
cuìng mäüt mãûnh âãö, X15 luän luän chè biãøu diãùn mäüt biãún. Tuy nhiãn âäúi våïi
caïc hàòng thç tçnh huäúng laûi khaïc : mäüt nguyãn tæí thãø hiãûn mäüt âäúi tæåüng
trong táút caí caïc mãûnh âãö, coï nghéa laì trong táút caí chæång trçnh.
mäüt cáúu truïc khaïc. Chàóng haûn ta coï thãø thay thãú thaình pháön thæï nháút bàòng
biãún Day (chuï yï tãn biãún bàõt âáöu båíi chæî hoa) thãø hiãûn báút kyì ngaìy naìo cuía
thaïng 9 :
date(Day, may, 1890)
Chuï yï ràòng Day laì mäüt biãún, coï thãø âæåüc raìng buäüc khi xæí lyï sau âoï.
Trong Prolog, vãö màût cuï phaïp, caïc âäúi tæåüng laì nhæîng haûng. Trong vê duû
trãn, may vaì date(Day, september, 2003) âãöu laì nhæîng haûng.
Moüi âäúi tæåüng coï cáúu truïc âãöu coï thãø âæåüc biãøu diãùn hçnh hoüc dæåïi daûng
cáy (tree), våïi haìm tæí laì gäúc, coìn caïc thaình pháön tham âäúi laì caïc nhaïnh cuía
cáy. Nãúu mäüt trong caïc thaình pháön laì mäüt cáúu truïc, thç thaình pháön âoï taûo
thaình mäüt cáy con cuía cáy ban âáöu. Hai haûng laì coï cuìng cáúu truïc nãúu coï
cuìng cáy biãøu diãùn vaì coï cuìng thaình pháön (pattern of variables). Haìm tæí cuía
gäúc âæåüc goüi laì haìm tæí chênh cuía haûng.
caïc tham âäúi
date
date( Day, september, 2003 )
Hçnh IV.1. Ngaìy thaïng laì mäüt âäúi tæåüng coï cáúu truïc :
(a) biãøu diãùn daûng cáy cuía cáúu truïc ; (b) giaíi thêch caïch viãút trong Prolog
Vê duû IV.2 :
Cáúu truïc (âån giaín) cuía mäüt cuäún saïch gäöm ba thaình pháön tiãu âãö vaì taïc
giaí cuîng laì caïc cáúu truïc (con), nàm xuáút baín laì mäüt biãún :
book(title(Name), author(Author), Year)
Vê duû IV.3 :
Xáy dæûng caïc âäúi tæåüng hçnh hoüc âån giaín trong khäng gian hai chiãöu.
Mäùi âiãøm âæåüc xaïc âënh båíi hai toaû âäü, hai âiãøm taûo thaình mäüt âæåìng thàóng,
ba âiãøm taûo thaình mäüt tam giaïc. Ta xáy dæûng caïc haìm tæí sau âáy :
point biãøu diãùn âiãøm,
seg biãøu diãùn mäüt âoaûn thàóng (segment),
triangle biãøu diãùn mäüt tam giaïc.
Måí âáöu vãö ngän ngæî Prolog 21
5 ⎯
(6, 4)
4 ⎯
P2 = (2, 3)
3 ⎯
2 ⎯ (4, 2)
1 ⎯ (7, 1)
P1 = (1, 1)
| | | | | | | |
1 2 3 4 5 6 7 8
Hçnh IV.2. Mäüt säú âäúi tæåüng hçnh hoüc âån giaín.
Tæì âoï, caïc âäúi tæåüng trãn Hçnh IV.2 âæåüc biãøu diãùn båíi caïc haûng nhæ sau :
P1 = point(1, 1)
P2 = point(2, 3)
S = seg(P1, P2) = seg(point(1, 1), point(2, 3))
T = triangle(point(4, 2), point(6, 4), point(7, 1))
Nãúu trong cuìng mäüt chæång trçnh, ta coï caïc âiãøm trong mäüt khäng gian
ba chiãöu, ta coï thãø âënh nghéa mäüt haìm tæí måïi laì point3 nhæ sau :
point3(X, Y, Z)
Prolog cho pheïp sæí duûng cuìng tãn hai cáúu truïc khaïc nhau. Vê duû :
point(X1, Y1) vaì point(X, Y, Z)
laì hai cáúu truïc khaïc nhau.
Trong cuìng mäüt chæång trçnh, nãúu mäüt tãn âoïng hai vai troì khaïc nhau,
nhæ træåìng håüp point åí trãn, thç Prolog seî càn cæï vaìo säú læåüng âäúi säú âãø
phán biãût. Cuìng mäüt tãn naìy seî tæång æïng våïi hai haìm tæí, mäüt haìm tæí coï
hai âäúi säú vaì mäüt haìm tæí coï ba âäúi säú. Nhæ váûy, mäüt haìm tæí âæåüc âënh
nghéa båíi hai yãúu täú :
(1) Tãn haìm tæí coï cuï phaïp laì cuï phaïp cuía caïc nguyãn tæí.
(2) Kêch thæåïc cuía haìm tæí laì säú caïc âäúi säú cuía noï.
Biãøu diãùn daûng cáy cuía caïc âäúi tæåüng âiãøm, âoaûn thàóng vaì tam giaïc trãn
âáy âæåüc cho trong Hçnh IV.3. Nhæ âaî trçnh baìy, moüi âäúi tæåüng cáúu truïc cuía
Prolog âãöu âæåüc biãøu diãùn dæåïi daûng cáy, xuáút hiãûn trong mäüt chæång trçnh
dæåïi daûng caïc haûng.
22 Láûp trçnh logic trong Prolog
1 1 2 3
4 2 6 4 7 1
Hçnh IV.3. Biãøu diãùn daûng cáy cuía caïc âäúi tæåüng.
+ -
a b c 5
Tuy nhiãn, ta khäng thãø raìng buäüc hai haûng date(D, M, 1890) vaì date(D1,
May, 2000), hay date(X, Y, Z) vaì point(X, Y, Z).
Cáúu truïc book(title(Name), author(Author)) âæåüc so khåïp våïi :
book(title(lord_of_the_rings), author(tolkien))
nhåì pheïp thãú :
Name = lord_of_the_rings
Author = tolkien
Thuáût toaïn håüp nháút Herbrand so khåïp hai haûng S vaì T :
(1) Nãúu S vaì T laì caïc hàòng, thç S vaì T chè coï thãø khåïp nhau nãúu vaì chè
nãúu chuïng coï cuìng giaï trë (chè laì mäüt âäúi tæåüng).
(2) Nãúu S laì mäüt biãún, T laì mäüt âäúi tæåüng naìo âoï báút kyì, thç S vaì T khåïp
nhau, våïi S âæåüc raìng buäüc våïi T. Tæång tæû, nãúu T laì mäüt biãún, thç T
âæåüc raìng buäüc våïi S.
(3) Nãúu S vaì T laì caïc cáúu truïc, thç S vaì T khåïp nhau nãúu vaì chè nãúu :
(a) S vaì T coï cuìng mäüt haìm tæí chênh, vaì
24 Láûp trçnh logic trong Prolog
(b) táút caí caïc thaình pháön laì khåïp nhau tæìng âäi mäüt.
Nhæ váûy, sæû raìng buäüc âæåüc xaïc âënh båíi sæû raìng buäüc cuía caïc thaình
pháön.
Ta coï thãø quan saït luáût thæï ba åí caïch biãøu diãùn caïc haûng dæåïi daûng cáy
trong Hçnh IV.5 dæåïi âáy. Quaï trçnh so khåïp âæåüc bàõt âáöu tæì gäúc (haìm tæí
chênh). Nãúu hai haìm tæí laì giäúng nhau, thç quaï trçnh seî âæåüc tiãúp tuûc våïi tæìng
càûp tham âäúi cuía chuïng. Moüi quaï trçnh so khåïp âæåüc xem nhæ mäüt daîy caïc
pheïp tênh âån giaín hån nhæ sau :
triangle = triangle
point(1, 1) = X
A = point(4, Y)
point(2, 3) = point(2, Z)
Moüi quaï trçnh so khåïp laì têch cæûc (positive), nãúu táút caí caïc quaï trçnh so
khåïp bäø tråü laì têch cæûc.
triangle
point A point
1 1 2 3
triangle
X point point
4 Y 2 Z
Mäüt âoaûn thàóng laì thàóng âæïng nãúu hoaình âäü (abscissa) cuía hai muït laì
bàòng nhau, tæång tæû, laì nàòm ngang nãúu tung âäü (ordinate) cuía hai muït laì
bàòng nhau.
Ta sæí duûng quan hãû âån phán âãø biãøu diãùn caïc tênh cháút naìy nhæ sau :
vertical(seg(point(X, Y), point(X, Y1))).
horizontal(seg(point(X, Y), point(X1, Y))).
Ta coï :
?- vertical(seg(point(1, 1), point(1, 2))).
Yes
?- vertical(seg(point(1, 1), point(2, Y))).
No
?- horizontal(seg(point(1, 1), point(2, Y))).
Y=1
Yes
point(X, Y1)
point(X, Y)
point(X1, Y)
point(X, Y)
Hçnh IV.6. Minh hoaû caïc âoaûn thàóng nàòm ngang vaì thàóng âæïng.
Våïi cáu hoíi thæï nháút, Prolog traí låìi Yes vç caïc sæû kiãûn âæåüc so khåïp âuïng.
Våïi cáu hoíi thæï hai, vç khäng coï sæû kiãûn naìo âæåüc so khåïp nãn Prolog traí låìi
No. Våïi cáu hoíi thæï ba, Prolog cho Y giaï trë 1 âãø âæåüc so khåïp âuïng.
Ta coï thãø âàût mäüt cáu hoíi täøng quaït hån nhæ sau : Cho biãút nhæîng âoaûn
thàóng thàóng âæïng coï mäüt muït cho træåïc laì (2, 3) ?
?- vertical(seg(point(2, 3), P)).
P = point(2, _0104)
Yes
Cáu traí låìi coï nghéa laì moüi âæåìng thàóng coï phæång trçnh X = 2 laì thàóng
âæïng. Chuï yï ràòng åí âáy, ta khäng nháûn âæåüc tãn biãún nhæ mong muäún (laì
Y), maì tuyì theo phiãn baín caìi âàût cuû thãø, Prolog seî taûo ra mäüt tãn biãún khi
thæûc hiãûn chæång trçnh, _0104 trong vê duû trãn, nhàòm traïnh âàût laûi tãn biãún
cuía NSD våïi hai lyï do nhæ sau. Thæï nháút, cuìng mäüt tãn biãún nhæng xuáút
26 Láûp trçnh logic trong Prolog
hiãûn trong caïc mãûnh âãö khaïc nhau thç seî biãøu diãùn nhæîng biãún khaïc nhau.
Thæï hai, do khi aïp duûng liãn tiãúp cuìng mäüt mãûnh âãö, chênh baín «copy» âæåüc
sæí duûng våïi mäüt bäü biãún khaïc.
Báy giåì ta âàût tiãúp mäüt cáu hoíi thuï vë nhæ sau : Coï täön taûi mäüt âoaûn
thàóng væìa thàóng âæïng væìa nàòm ngang hay khäng ?
?- vertical(S), horizontal(S).
S = seg(point(_00E8, _00EC), point(_00E8, _00EC))
Yes
Cáu traí låìi coï nghéa laì moüi âoaûn thàóng khi suy biãún thaình mäüt âiãøm thç
væìa thàóng âæïng, laûi væìa nàòm ngang. Ta tháúy ràòng kãút quaí nháûn âæåüc laì nhåì
so khåïp. ÅÍ âáy, caïc tãn biãún _00E8 vaì _00EC, tæång æïng våïi X vaì Y, âaî âæåüc
taûo ra båíi Prolog.
Sau âáy laì mäüt vê duû khaïc minh hoaû hai cáúu truïc âæåüc säú khåïp våïi nhau.
student
jean X address
maljuin caen
student
jean info Y
8. Cho quan hãû parent âæåüc âënh nghéa trong pháön lyï thuyãút cho biãút kãút
quaí cuía caïc cáu hoíi sau :
a) ?- parent(jim , X).
b) ?- parent( X , jim).
c) ?-parent(pam , X) , parent( X , part).
d) ?- parent(pam , X) , parent( X , y ) , parent(y , jim).
9. Viãút caïc mãûnh âãö Prolog diãùn taí caïc cáu hoíi liãn quan âãún quan hãû
parent :
a) Ai laì cha meû cuía Pat ?
b) Liz coï con khäng ?
c) Ai laì äng baì (grandparent) cuía Pat ?
10. Viãút trong Prolog caïc mãûnh âãö sau :
a) Ai coï mäüt âæïa treí ngæåìi âoï laì haûnh phuïc.
Hæåïng dáùn : Xáy dæûng quan hãû mäüt ngäi happy.
b) Våïi moüi X, nãúu X coï mäüt con maì ngæåìi con naìy coï mäüt chë em gaïi, thç X
coï hai con (xáy dæûng quan hãû have_two_children).
11. Âënh nghéa quan hãû grandchild bàòng caïch sæí duûng quan hãû parent.
Hæåïng dáùn : tçm hiãøu quan hãû grandparent.
30 Láûp trçnh logic trong Prolog
12. Âënh nghéa quan hãû aunt( X, Y ) bàòng caïch sæí duûng quan hãû parent.
Âãø thuáûn tiãûn, coï thãø veî så âäö minh hoüa.
13. Caïc pheïp so khåïp dæåïi âáy coï âuïng khäng ? Nãúu âuïng, cho biãút caïc raìng
buäüc biãún tæång æïng ?
a) point( A , B ) = point( 1 , 2 )
b) point( A , B ) = point( X , Y, Z )
c) addition( 2 , 2 ) = 4
d) +( 2 , D ) = +( E , 2 )
e) triangle( point( -1 , 0 ) , P2, P3 ) = triangle( P1, point( 1, 0 ), point( 0,
Y))
Caïc raìng buäüc åí âáy âaî âënh nghéa mäüt låïp caïc tam giaïc. Laìm caïch
naìo âãø mä taí låïp naìy ?
14. Sæí duûng mä taí caïc âæåìng thàóng âaî cho trong baìi hoüc, tçm mäüt haûng biãùu
diãùn moüi âæåìng thàóng âæïng X = 5.
15. Cho hçnh chæî nháût âæåüc biãùu diãùn båíi haûng: rectangle(P1, P2, P3, P4).
Våïi Pi laì caïc âènh cuía hçnh chæî nháût theo chiãöu dæång, haîy âënh nghéa
quan hãû :
regular( R )
laì âuïng nãúu R laì mäüt hçnh chæî nháût coï caïc caûnh thàóng âæïng vaì nàòm
ngang (song song våïi caïc truûc toüa âäü).
CHÆÅNG 2
Prolog coï cuï phaïp laì nhæîng cäng thæïc lägich vë tæì báûc mäüt (first order
predicate logic), âæåüc viãút dæåïi daûng caïc mãûnh âãö (caïc læåüng tæí ∀ vaì ∃ khäng
xuáút hiãûn mäüt caïch tæåìng minh), nhæng haûn chãú chè âån thuáön åí daûng mãûnh
âãö Horn, laì nhæîng mãûnh âãö chè coï êt nháút mäüt træûc kiãûn dæång (positive
literals). Nàm 1981, Clocksin vaì Mellish âaî âæa ra mäüt chæång trçnh Prolog
chuyãøn caïc cäng thæïc tênh vë tæì báûc mäüt thaình daûng caïc mãûnh âãö.
Caïch Prolog diãùn giaíi chæång trçnh laì theo kiãøu Toaïn hoüc : Prolog xem
caïc sæû kiãûn vaì caïc luáût nhæ laì caïc tiãn âãö, xem cáu hoíi cuía NSD nhæ laì mäüt
âënh lyï cáön phoíng âoaïn. Prolog seî tçm caïch chæïng minh âënh lyï naìy, nghéa laì
chè ra ràòng âënh lyï coï thãø âæåüc suy luáûn mäüt caïch lägich tæì caïc tiãn âãö.
Vãö màût thuí tuûc, Prolog sæí duûng phæång phaïp suy diãùn quay lui (back
chaining) âãø håüp giaíi (resolution) baìi toaïn, âæåüc goüi laì chiãún læåüc håüp giaíi SLD
(Selected, Linear, Definite : Linear resolution with a Selection function for
Definite sentences) do J. Herbrand vaì A. Robinson âãö xuáút nàm 1995.
31
32 Láûp trçnh lägich trong Prolog
Coï thãø toïm tàõt nhæ sau : âãø chæïng minh P(a), ngæåìi ta tçm sæû kiãûn
P(t)
hoàûc mäüt luáût :
P(t) :- L1, L2, …, Ln
sao cho a coï thãø håüp nháút (unifiable) âæåüc våïi t nhåì so khåïp. Nãúu tçm âæåüc
P(t) laì sæû kiãûn nhæ váûy, viãûc chæïng minh kãút thuïc. Coìn nãúu tçm âæåüc P(t) laì
luáût, cáön láön læåüt chæïng minh vãú bãn phaíi L1, L2, ..., Ln cuía noï.
Trong Prolog, cáu hoíi luän luän laì mäüt daîy tæì mäüt âãún nhiãöu âêch. Prolog
traí låìi mäüt cáu hoíi bàòng caïch tçm kiãúm âãø xoaï (erase) táút caí caïc âêch. Xoaï
mäüt âêch nghéa laì chæïng minh ràòng âêch naìy âæåüc thoaí maîn, våïi giaí thiãút
ràòng caïc quan hãû cuía chæång trçnh laì âuïng. Noïi caïch khaïc, xoaï mäüt âêch coï
nghéa laì âêch naìy âæåüc suy ra mäüt caïch lägich båíi caïc sæû kiãûn vaì luáût chæïa
trong chæång trçnh.
Nãúu coï caïc biãún trong cáu hoíi, Prolog tçm caïc âäúi tæåüng âãø thay thãú vaìo
caïc biãún, sao cho âêch âæåüc thoaí maîn. Sæû raìng buäüc giaï trë cuía caïc biãún
tæång æïng våïi viãûc hiãøn thë caïc âäúi tæåüng naìy. Nãúu Prolog khäng thãø tçm
âæåüc raìng buäüc cho caïc biãún sao cho âêch âæåüc suy ra tæì chæång trçnh thç noï
seî traí låìi No.
Theo nghéa khai baïo, ta âoüc chuïng theo hai caïch nhæ sau :
• P laì âuïng nãúu caí Q vaì R âãöu âuïng.
• Q vaì R dáùn ra P.
Theo nghéa thuí tuûc, ta cuîng âoüc chuïng theo hai caïch nhæ sau :
• Âãø giaíi baìi toaïn P, âáöu tiãn, giaíi baìi toaïn con Q, sau âoï giaíi baìi toaïn
con R.
• Âãø xoaï P, âáöu tiãn, xoaï Q, sau âoï xoaï R.
Sæû khaïc nhau giæîa nghéa khai baïo vaì nghéa thuí tuûc laì åí chäù, nghéa thuí
tuûc khäng âënh nghéa caïc quan hãû lägich giæîa pháön âáöu cuía mãûnh âãö vaì caïc
âêch cuía thán, maì chè âënh nghéa thæï tæû xæí lyï caïc âêch.
hasachild(jafa) :-
parent(jafa, small(iago)).
Cho træåïc mäüt chæång trçnh vaì mäüt âêch G, nghéa khai baïo noïi ràòng :
Mäüt âêch G laì âuïng (thoaí maîn, hay suy ra âæåüc tæì chæång trçnh mäüt caïch
logic) nãúu vaì chè nãúu
(1) täön taûi mäüt mãûnh âãö C cuía chæång trçnh sao cho
(2) täön taûi mäüt thãø nghiãûm I cuía mãûnh âãö C sao cho:
(a) pháön âáöu cuía I laì giäúng hãût G, vaì
(b) moüi âêch cuía pháön thán cuía I laì âuïng.
Âënh nghéa trãn âáy aïp duûng âæåüc cho caïc cáu hoíi Prolog. Cáu hoíi laì mäüt
danh saïch caïc âêch ngàn caïch nhau båíi caïc dáúu pháøy. Mäüt danh saïch caïc
âêch laì âuïng nãúu táút caí caïc âêch cuía danh saïch laì âuïng cho cuìng mäüt raìng
buäüc cuía caïc biãún. Caïc giaï trë cuía caïc biãún laì nhæîng giaï trë raìng buäüc täøng
quaït nháút.
• mäùi dáúu pháøy (comma) âàût giæîa caïc mãûnh âãö, hay caïc âêch, âoïng vai troì
pheïp häüi (conjunction). Vãö màût lägich, chuïng phaíi âuïng táút caí.
• mäùi dáúu cháúm pháøy (semicolon) âàût giæîa caïc mãûnh âãö, hay caïc âêch,
âoïng vai troì pheïp tuyãøn (disjunction). Luïc naìy chè cáön mäüt trong caïc
âêch cuía danh saïch laì âuïng.
Ngæî nghéa cuía chæång trçnh Prolog 35
Vê duû II.2 :
P :- Q; R.
âæåüc âoüc laì : P âuïng nãúu Q âuïng hoàûc R âuïng. Ngæåìi ta cuîng coï thãø viãút taïch
ra thaình hai mãûnh âãö :
P :- Q.
P :- R.
Trong Prolog, dáúu pháøy (pheïp häüi) coï mæïc âäü æu tiãn cao hån dáúu cháúm
pháøy (pheïp tuyãøn). Vê duû :
P :- Q, R; S, T, U.
âæåüc hiãøu laì :
P :- (Q, R); (S, T, U).
vaì coï thãø âæåüc viãút thaình hai mãûnh âãö :
P :- (Q, R).
P :- (S, T, U).
Hai mãûnh âãö trãn âæåüc âoüc laì : P âuïng nãúu hoàûc caí Q vaì R âãöu âuïng,
hoàûc caí S, T vaì U âãöu âuïng.
Vãö nguyãn tàõc, thæï tæû thæûc hiãûn caïc mãûnh âãö trong mäüt goïi laì khäng
quan troüng, tuy nhiãn trong thæûc tãú, cáön chuï yï tän troüng thæï tæû cuía caïc
mãûnh âãö. Prolog seî láön læåüt thæûc hiãûn theo thæï tæû xuáút hiãûn caïc mãûnh âãö
trong goïi vaì trong chæång trçnh theo mä hçnh tuáön tæû bàòng caïch thæí quay lui
maì ta seî xeït sau âáy.
P(a) :- Q(c). P(X) âuïng nãùu X = a vaì Q(c) âuïng P(X) ⇔ X = a ∧ Q(c)
P(a) :- Q(c). P(X) âuïng nãùu hoàûc (X = a vaì Q(c) P(X) ⇔ (X = a ∧ Q(c))
P(b). âuïng) hoàûc X = b ∨ (X = b)
36 Láûp trçnh lägich trong Prolog
P(X) :- Våïi moüi giaï trë cuía X, P(X) âuïng nãùu Q(X)
P(X) ⇔ Q(X)
Q(X). âuïng
p(a), Q(b). Coï phaíi caí p(a) vaì Q(b) âãöu âuïng ?
P(X). Cho biãút giaï trë cuía X âãø P(X) laì âuïng ?
P(X), Q(X, Y). Cho biãút caïc giaï trë cuía X vaì cuía Y âãø P(X) vaì Q(X, Y) âãöu
laì âuïng ?
Ngæî nghéa cuía chæång trçnh Prolog 37
Hçnh II.1. Mä hçnh vaìo/ra cuía mäüt thuí tuûc thæûc hiãûn mäüt danh saïch caïc âêch.
Goüi thuí tuûc naìy laì execute (thæûc hiãûn), caïi vaìo vaì caïi ra cuía noï nhæ sau :
Caïi vaìo : mäüt chæång trçnh vaì mäüt danh saïch caïc âêch
Caïi ra : mäüt dáúu hiãûu thaình cäng/tháút baûi vaì mäüt raìng buäüc caïc biãún
Nghéa cuía hai caïi ra nhæ sau :
(1) Dáúu hiãûu thaình cäng/tháút baûi laì Yes nãúu caïc âêch âæåüc thoaí maîn (thaình
cäng), laì No nãúu ngæåüc laûi (tháút baûi).
(2) Sæû raìng buäüc caïc biãún chè xaíy ra nãúu chæång trçnh âæåüc thæûc hiãûn.
38 Láûp trçnh lägich trong Prolog
Vê duû II.3 :
Minh hoaû caïch Prolog traí låìi cáu hoíi cho vê duû chæång trçnh gia hãû træåïc
âáy nhæ sau :
Âêch cáön tçm laì :
?- ancestor(tom, pat)
Ta biãút ràòng parent(bob, pat) laì mäüt sæû kiãûn. Âãø sæí duûng sæû kiãûn naìy vaì
luáût 1 (vãö täø tiãn træûc tiãúp), ta coï thãø kãút luáûn ràòng ancestor(bob, pat). Âáy laì
mäüt sæû kiãûn keïo theo : sæû kiãûn naìy khäng coï màût trong chæång trçnh, nhæng
coï thãø âæåüc suy ra tæì caïc luáût vaì sæû kiãûn khaïc. Ta coï thãø viãút goün sæû suy diãùn
naìy nhæ sau :
parent(bob, pat) ⇒ ancestor(bob, pat)
Nghéa laì parent(bob, pat)keïo theo ancestor(bob, pat) båíi luáût 1. Ta laûi biãút
ràòng parent(tom, bob) cuîng laì mäüt sæû kiãûn. Màût khaïc, tæì sæû kiãûn âæåüc suy
diãùn ancestor(bob, pat), luáût 2 (vãö täø tiãn giaïn tiãúp) cho pheïp kãút luáûn ràòng
ancestor(tom, pat). Quaï trçnh suy diãùn hai giai âoaûn naìy âæåüc viãút :
parent(bob, pat) ⇒ ancestor(bob, pat)
parent(tom, bob) vaì ancestor(bob, pat) ⇒ ancestor(tom, pat)
Ta væìa chè ra caïc giai âoaûn âãø xoaï mäüt âêch, goüi laì mäüt chæïng minh. Tuy
nhiãn, ta chæa chè ra laìm caïch naìo Prolog nháûn âæåüc mäüt chæïng minh nhæ
váûy.
Prolog nháûn âæåüc pheïp chæïng minh naìy theo thæï tæû ngæåüc laûi nhæîng gç
âaî trçnh baìy. Thay vç xuáút phaït tæì caïc sæû kiãûn chæïa trong chæång trçnh,
Prolog bàõt âáöu båíi caïc âêch vaì, bàòng caïch sæí duûng caïc luáût, noï thay thãú caïc
âêch naìy båíi caïc âêch måïi, cho âãún khi nháûn âæåüc caïc sæû kiãûn så cáúp.
Âãø xoaï âêch :
?- ancestor(tom, pat).
Prolog tçm kiãúm mäüt mãûnh âãö trong chæång trçnh maì âêch naìy âæåüc suy diãùn
ngay láûp tæïc. Roî raìng chè coï hai mãûnh âãö thoaí maîn yãu cáöu naìy laì luáût 1 vaì
luáût 2, liãn quan âãún quan hãû ancestor. Ta noïi ràòng pháön âáöu cuía caïc luáût
naìy tæång æïng våïi âêch.
Ngæî nghéa cuía chæång trçnh Prolog 39
Hai mãûnh âãö naìy biãøu diãùn hai khaí nàng maì Prolog phaíi khai thaïc xæí lyï.
Prolog bàõt âáöu choün xæí lyï mãûnh âãö thæï nháút xuáút hiãûn trong chæång trçnh :
ancestor(X, Z) :- parent(X, Z).
Do âêch laì ancestor(tom, pat), caïc biãún phaíi âæåüc raìng buäüc nhæ sau :
X = tom, Z = pat
Hçnh dæåïi âáy biãøu diãùn giai âoaûn chuyãøn mäüt âêch thaình âêch måïi sæí
duûng mäüt luáût. Tháút baûi xaíy ra khi khäng coï pháön âáöu naìo trong caïc mãûnh
âãö cuía chæång trçnh tæång æïng våïi âêch parent(tom, pat).
ancestor(tom, pat)
Båíi luáût 1
parent(tom, pat)
Luïc naìy Prolog phaíi tiãún haình quay lui (backtracking) tråí laûi âêch ban
âáöu, âãø tiãúp tuûc xæí lyï mãûnh âãö khaïc laì luáût thæï hai :
ancestor(X, Z) :- parent(X, Y), ancestor(Y, Z).
Tæång tæû bæåïc xæí lyï thæï nháút, caïc biãún X vaì Z âæåüc raìng buäüc nhæ sau :
X = tom, Z = pat
Âêch phêa trãn ancestor(tom, pat)âæåüc thay thãú båíi hai âêch laì :
parent(tom, Y), ancestor(Y, pat).
Nhæng luïc naìy, Y chæa coï giaï trë. Luïc naìy cáön xoaï hai âêch. Prolog seî tiãún
haình xoaï theo thæï tæû xuáút hiãûn cuía chuïng trong chæång trçnh. Âäúi våïi âêch
thæï nháút, viãûc xoaï ráút dãù daìng vç âoï laì mäüt trong caïc sæû kiãûn cuía chæång
trçnh. Sæû tæång æïng sæû kiãûn dáùn âãún Y âæåüc raìng buäüc båíi giaï trë bob.
Caïc giai âoaûn thæûc hiãûn âæåüc mä taí båíi cáy håüp giaíi sau âáy :
40 Láûp trçnh lägich trong Prolog
ancestor(tom, pat)
Tháút baûi
parent(tom, pat) parent(tom, Y)
ancestor(Y, pat)
Hçnh II.3. Caïc giai âoaûn thæûc hiãûn xæí lyï xoaï âêch.
Sau khi âêch thæï nháút parent(tom, bob) thoaí maîn, coìn laûi âêch thæï hai :
ancestor(bob, pat)
cuîng phaíi âæåüc thoaí maîn Mäüt láön næîa, luáût 1 âæåüc sæí duûng. Chuï yï ràòng viãûc
aïp duûng láön thæï hai cuìng luáût naìy khäng liãn quan gç âãún láön aïp duûng thæï
nháút. Prolog sæí duûng caïc biãún måïi mäùi láön luáût âæåüc goüi âãún. Luáût 1 báy giåì
coï thãø âæåüc âàût tãn laûi nhæ sau :
ancestor(X’, Z’) :- parent(X’, Z’).
Pháön âáöu phaíi tæång æïng våïi âêch thæï nháút, ancestor(bob, pat), tæïc laì :
X’ = bob, Z’ = pat
ancestor(tom, pat)
Båíi luáût 1
Thaình cäng
parent(bob, pat)
Hçnh II.4. Quaï trçnh thæûc hiãûn xoaï âêch ancestor(tom, pat).
Tæì âoï âêch (trong pháön thán) phaíi thay thãú båíi :
parent(bob, pat)
Ngæî nghéa cuía chæång trçnh Prolog 41
Âêch naìy âæåüc thoaí maîn ngay láûp tæïc, vç chênh laì mäüt sæû kiãûn trong
chæång trçnh. Quaï trçnh xæí lyï âæåüc minh hoaû laûi âáöy âuí trong Hçnh II.4.
Hçnh 2.4. coï daûng mäüt cáy. Mäùi nuït tæång æïng våïi mäüt âêch, hay mäüt
danh saïch caïc âêch cáön thoaí maîn. Mäùi cung näúi hai nuït tæång æïng våïi viãûc
aïp duûng mäüt luáût trong chæång trçnh. Viãûc aïp duûng mäüt luáût cho pheïp
chuyãøn caïc âêch cuía mäüt nuït thaình caïc âêch måïi cuía mäüt nuït khaïc. Âêch trãn
cuìng (gäúc cuía cáy) âæåüc xoaï khi tçm âæåüc mäüt con âæåìng âi tæì gäúc âãún laï coï
nhaîn laì thaình cäng. Mäüt nuït laï coï nhaîn laì thaình cäng khi trong nuït laì mäüt
sæû kiãûn cuía chæång trçnh. Viãûc thæûc thi mäüt chæång trçnh Prolog laì viãûc tçm
kiãúm nhæîng con âæåìng nhæ váûy.
Nhaïnh bãn phaíi chæïng toí ràòng coï thãø xoaï âêch.
Trong quaï trçnh tçm kiãúm, coï thãø xaíy ra khaí nàng laì Prolog âi trãn mäüt
con âæåìng khäng täút. Khi gàûp nuït chæïa mäüt sæû kiãûn khäng täön taûi trong
chæång trçnh, xem nhæ tháút baûi, nuït âæåüc gàõïn nhaîn tháút baûi, ngay láûp tæïc
Prolog tæû âäüng quay lui lãn nuït phêa trãn, choün aïp duûng mäüt mãûnh âãö tiãúp
theo coï màût trong nuït naìy âãø tiãúp tuûc con âæåìng måïi, chæìng naìo thaình cäng.
Vê duû trãn âáy, ta âaî giaíi thêch mäüt caïch khäng hçnh thæïc caïch Prolog traí
låìi cáu hoíi. Thuí tuûc execute dæåïi âáy mä taí hçnh thæïc vaì coï hãû thäúng hån vãö
quaï trçnh naìy.
Âãø thæûc hiãûn danh saïch caïc âêch :
G1, G2, ..., Gm
Nãúu khäng tçm tháúy mäüt mãûnh âãö naìo nhæ váûy, thuí tuûc råi vaìo tçnh traûng
tháút baûi.
42 Láûp trçnh lägich trong Prolog
khi âoï, caïc biãún cuía C âæåüc âàût tãn laûi âãø nháûn âæåüc mäüt biãún thãø C’
khäng coï biãún naìo chung våïi danh saïch G1, G2, ..., Gm.
Mãûnh âãö C’ nhæ sau :
H’ :- D’1, ..., D’n
Giaí sæí S laì raìng buäüc cuía caïc biãún tæì viãûc so khåïp giæîa G1 vaì H’, Prolog
thay thãú G1 båíi D’1, ..., D’n trong danh saïch caïc âêch âãø nháûn âæåüc mäüt danh
saïch måïi :
D1’, ..., Dn’, G2, ..., Gm
Chuï yï ràòng nãúu C laì mäüt sæû kiãûn, khi âoï, n=0 vaì danh saïch måïi seî ngàõn
hån danh saïch cuî. Træåìng håüp danh saïch måïi räùng, kãút quaí thaình cäng.
Thay thãú caïc biãún cuía danh saïch måïi naìy båíi caïc giaï trë måïi chè âënh båíi
raìng buäüc S, ta nháûn âæåüc mäüt danh saïch caïc âêch måïi :
D"1, ..., D"n, G"2, ..., G"m
Thæûc hiãûn thuí tuûc mäüt caïch âãû quy cho danh saïch caïc âêch måïi naìy. Nãúu
kãút thuïc thaình cäng, tiãúp tuûc thæûc hiãûn danh saïch ban âáöu. Trong træåìng
håüp ngæåüc laûi, Prolog boí qua danh saïch caïc âêch âãø quay lui laûi thuí tuûc
scrutinize. Quaï trçnh tçm kiãúm caïc mãûnh âãö trong chæång trçnh âæåüc bàõt âáöu
laûi tæì sau mãûnh âãö C, våïi mäüt mãûnh âãö måïi.
Ngæî nghéa cuía chæång trçnh Prolog 43
Quaï trçnh thæûc hiãûn thuí tuûc execute âæåüc mä taí nhæ sau :
Sau âáy laì thuí tuûc execute âæåüc viãút bàòng giaí ngæî Pascal.
Procedure execute(program, goallist, success);
{ Tham âäúi vaìo :
program danh saïch caïc mãûnh âãö
goallist danh saïch caïc âêch
Tham âäúi ra :
success kiãøu Boolean, laì true nãúu goallist laì true âäúi våïi tham âäúi
program
Caïc biãún cuûc bäü :
goal âêch
othergoals danh saïch caïc âêch
satisfied kiãøu Boolean
matchOK kiãøu Boolean
process raìng buäüc cuía caïc biãún
H, H’, D1, D1’, ..., Dn, Dn’ caïc âêch
Caïc haìm phuû :
empty(L) coï giaï trë true nãúu L laì danh saïch räùng
head(L) traí vãö pháön tæí âáöu tiãn cuía danh saïch L
tail(L) traí vãö danh saïch L sau khi âaî boí âi pháön tæí âáöu tiãn
add(L1, L2) gheïp danh saïch L2 vaìo sau danh saïch L1
match(T1, T2, matchOK, process)
so khåïp caïc haûng T1 vaì T2, nãúu thaình cäng,
44 Láûp trçnh lägich trong Prolog
biãún matchOK coï giaï trë true, vaì process chæïa caïc raìng
buäüc tæång æïng våïi caïc biãún.
substitute(process, goals)
thay thãú caïc biãún cuía goals båíi giaï trë raìng buäüc tæång æïng
trong process.
}
begin { execute_main }
if empty(goallist) then success:= true
else begin
goal:= head(goallist);
othergoals:= tail(goallist);
satisfied:= false;
while not satisfied and there_are_again_some_terms do begin
Let the following clause of program is:
H :- D1, ..., Dn
constructing a variant of this clause:
H’ :- D1’, ..., Dn’
match(goal, H’, matchOK, process)
if matchOK then begin
newgoals:= add([ D1’, ..., Dn’ ], othergoals);
newgoals:= substitute(process, newgoals);
execute(program, newgoals, satisfied)
end { if }
end; { while }
satisfied:= satisfied
end
end; { execute_main }
Tæì thuí tuûc execute trãn âáy, ta coï mäüt säú nháûn xeït sau. Træåïc hãút, thuí
tuûc khäng mä taí laìm caïch naìo âãø nháûn âæåüc raìng buäüc cuäúi cuìng cho caïc
biãún. Chênh raìng buäüc S âaî dáùn âãún thaình cäng nhåì caïc låìi goüi âãû quy.
Mäùi láön låìi goüi âãû quy execute tháút baûi (tæång æïng våïi mãûnh âãö C),
thuí tuûc scrutinize tçm kiãúm mãûnh âãö tiãúp theo ngay sau mãûnh âãö C. Quaï
trçnh thæûc thi laì hiãûu quaí, vç Prolog boí qua nhæîng pháön vä êch âãø reî sang
nhaïnh khaïc.
Ngæî nghéa cuía chæång trçnh Prolog 45
Luïc naìy, moüi raìng buäüc cho biãún thuäüc nhaïnh vä êch bë loaûi boí hoaìn toaìn.
Prolog seî láön læåüt duyãût hãút táút caí caïc con âæåìng coï thãø âãø âãún thaình cäng.
Ta cuîng âaî tháúy ràòng ngay sau khi coï mäüt kãút quaí têch cæûc, NSD coï thãø
yãu cáöu hãû thäúng quay lui âãø tçm kiãúm mäüt kãút quaí måïi. Chi tiãút naìy âaî
khäng âæåüc xæí lyï trong thuí tuûc execute. Trong caïc caìi âàût Prolog hiãûn nay,
nhiãöu khaí nàng måïi âaî âæåüc thãm vaìo nhàòm âaût hiãûu quaí täúi æu. Khäng
phaíi moüi mãûnh âãö trong chæång trçnh âãöu âæåüc duyãût âãún, maì chè duyãût
nhæîng mãûnh âãö coï liãn quan âãún âêch hiãûn haình.
Vê duû II.4 :
Cho chæång trçnh :
thick(bear). % clause 1
thick(elephant). % clause 2
small(cat). % clause 3
brown(bear). % clause 4
grey(elephant). % clause 5
black(cat). % clause 6
dark(Z) :- black(Z). % clause 7: all this who is black is dark
dark(Z) :- brown(Z). % clause 8: all this who is brown is dark
Cáu hoíi :
?- dark(X), thick(X). % who is thick and dark ?
X = bear
Yes
(1) Danh saïch ban âáöu cuía caïc âêch laì : dark(X), thick(X).
(2) Tçm kiãúm (duyãût) tæì âáöu âãún cuäúi chæång trçnh mäüt mãûnh âãö coï pháön
âáöu tæång æïng våïi âêch âáöu tiãn dark(X). Prolog tçm âæåüc mãûnh âãö 7 :
dark(Z) :- black(Z).
Thay thãú âêch âáöu tiãn båíi pháön thán cuía mãûnh âãö 7 sau khi âaî âæåüc
raìng buäüc (thãú biãún Z båíi X) âãø nháûn âæåüc mäüt danh saïch caïc âêch
måïi :
black(X), thick(X).
(3) Tçm kiãúm trong chæång trçnh mäüt mãûnh âãö sao cho âêch con black(X)
âæåüc so khåïp : tçm âæåüc mãûnh âãö 6 laì sæû kiãûn black(cat). Luïc naìy,
raìng buäüc thaình cäng, danh saïch caïc âêch thu goün thaình :
thick(cat)
46 Láûp trçnh lägich trong Prolog
(4) Tçm kiãúm âêch con thick(cat). Do khäng tçm tháúy mãûnh âãö naìo thoaí
maîn, Prolog quay lui laûi giai âoaûn (3). Raìng buäüc X=cat bë loaûi boí.
Danh saïch caïc âêch tråí thaình :
black(X), thick(X).
Tiãúp tuûc tçm kiãúm trong chæång trçnh bàõt âáöu tæì mãûnh âãö 6. Do
khäng tçm tháúy mãûnh âãö naìo thoaí maîn, Prolog quay lui laûi giai âoaûn
(2) âãø tiãúp tuûc tçm kiãúm bàõt âáöu tæì mãûnh âãö 7. Kãút quaí tçm âæåüc
mãûnh âãö 8 :
dark(Z) :- brown(Z).
Sau khi thay thãú båíi brown(X)trong danh saïch caïc âêch, ta nháûn
âæåüc :
brown(X), thick(X)
(5) Tçm kiãúm cho raìng buäüc brown(X), âæåüc kãút quaí laì brown(bear). Mãûnh
âãö naìy laì mäüt sæû kiãûn, danh saïch caïc âêch thu goün laûi thaình :
thick(bear)
(6) Viãûc tçm kiãúm trong chæång trçnh dáùn âãún kãút quaí thick(bear). Do âáy
laì mäüt sæû kiãûn, danh saïch caïc âêch tråí nãn räùng. Âiãöu naìy chæïng toí
chæång trçnh âaî thæûc hiãûn thaình cäng, sæû raìng buäüc cho biãún laì :
X = bear
Quaï trçnh thæûc hiãûn âæåüc giaíi thêch trong hçnh dæåïi âáy.
dark(X), thick(X)
brown(bear).
black(cat). Quay lui
(X|bear)
(X|cat)
thick(cat) thick(bear)
Hçnh II.6. Quaï trçnh thæûc hiãûn xoaï âêch dark(X), thick(X).
Ngæî nghéa cuía chæång trçnh Prolog 47
II.5. Täø håüp caïc yãúu täú khai baïo vaì thuí tuûc
Ngæåìi ta thæåìng quan tám âãún tênh æu viãût cuía Prolog laì khaí nàng tæû
quaín lyï caïc chi tiãút thuí tuûc. Âiãöu naìy cho pheïp NLT (NLT) dæû kiãún træåïc
âæåüc nghéa khai baïo cuía mäüt chæång trçnh mäüt caïch âäüc láûp våïi nghéa thuí
tuûc cuía noï. Vãö nguyãn tàõc, do kãút quaí thæûc hiãûn cuía mäüt chæång trçnh phuû
thuäüc vaìo pháön khai baïo, nãn phaíi khai baïo âáöy âuí caïc sæû kiãûn, luáût vaì quan
hãû khi láûp trçnh. Âiãöu naìy mang tênh thæûc tiãùn, vç luän luän caïc yãúu täú khai
baïo cuía mäüt chæång trçnh dãù hiãøu hån so våïi caïc chi tiãút thuí tuûc.
Âãø táûn duûng âæåüc khaí nàng tæû quaín lyï caïc chi tiãút thuí tuûc cuía Prolog,
NLT phaíi táûp trung âàûc biãût vaìo yãúu täú khai baïo, traïnh nháöm láùn trong
chæìng mæûc coï thãø båíi caïc chi tiãút thæûc hiãûn chæång trçnh. Cáön âãø cho Prolog
tæû giaíi quyãút caïc chi tiãút mang tênh thuí tuûc naìy.
Nhåì tiãúp cáûn khai baïo, láûp trçnh trãn Prolog luän luän thuáûn tiãûn hån so
våïi caïc ngän ngæî thuí tuûc khaïc nhæ Pascal. Tuy nhiãn, tiãúp cáûn khai baïo
khäng phaíi luän luän âáöy âuí. Nhæ seî tháúy sau naìy, âäúi våïi caïc chæång trçnh
låïn, khäng thãø loaûi boí hoaìn toaìn tênh tiãúp cáûn thuí tuûc, do tênh hiãûu quaí thæûc
tiãùn cuía noï khi thæûc hiãûn chæång trçnh.
Vç váûy, tuyì theo chæång trçnh Prolog maì sæí duûng hoaìn toaìn yãúu täú khai
baïo, loaûi boí yãúu täú thuí tuûc khi raìng buäüc thæûc tiãùn cho pheïp.
Nhæ seî tháúy trong chæång sau ràòng viãûc sàõp âàût thæï tæû caïc mãûnh âãö vaì
caïc âêch cuîng nhæ thæï tæû caïc haûng trong mäùi mãûnh âãö coï vai troì quan troüng
trong viãûc tçm ra kãút quaí. Màût khaïc, mäüt säú chæång trçnh tuy âuïng âàõn vãö
màût khai baïo nhæng laûi khäng chaûy âæåüc trong thæûc tãú. Ranh giåïi giæîa yãúu täú
thuí tuûc vaì yãúu täú khai baïo ráút khoï suy xeït. Mãûnh âãö sau âáy laì mäüt minh
chæïng vãö viãûc khai baïo âuïng, nhæng laûi hoaìn toaìn vä êch vãö màût chaûy chæång
trçnh :
ancestor(X, Z) :- ancestor(X, Z).
Do nhæîng tiãún bäü cuía kyî thuáût láûp trçnh, ngæåìi ta quan tám âãún nghéa
khai baïo âãø boí qua nhæîng chi tiãút thuí tuûc, táûn duûng nhæîng chi tiãút khai baïo
laìm låìi giaíi âån giaín hån vaì dãù hiãøu hån. Khäng phaíi laì NLT, maì chênh hãû
thäúng phaíi quaín lyï nhæîng chi tiãút thuí tuûc. Prolog laì ngän ngæî nhàòm vaìo muûc
âêch naìy. Nhæ ta âaî tháúy, Prolog chè giuïp quaín lyï âuïng âàõn mäüt pháön nhæîng
chi tiãút thuí tuûc, maì khäng thãø quaín lyï âæåüc táút caí.
48 Láûp trçnh lägich trong Prolog
Mäüt yãúu täú thæûc tãú næîa laì ngæåìi ta dãù daìng cháúp nháûn mäüt chæång trçnh
chaûy âæåüc (âuïng nghéa thuí tuûc) hån laì mäüt chæång trçnh chè âuïng âàõn vãö
màût khai baïo maì chæa chaûy âæåüc. Vç váûy, âãø giaíi quyãút mäüt baìi toaïn naìo âoï
mäüt caïch coï låüi, ngæåìi ta táûp trung giaíi quyãút nhæîng yãúu täú khai baïo, tiãún
haình chaûy thæí chæång trçnh trãn maïy, räöi sàõp âàût laûi caïc mãûnh âãö vaì caïc
âêch nãúu noï váùn chæa chaûy âuïng vãö màût thuí tuûc.
Hçnh III.1. Minh hoaû baìi toaïn con khè vaì quaí chuäúi.
Ta sæí duûng mäüt biãún thãø (variant) cuía baìi toaïn nhæ sau : mäüt con khè
âang åí træåïc cæía mäüt càn phoìng. Trong phoìng, åí chênh giæîa tráön coï treo mäüt
quaí chuäúi. Con khè âang âoïi nãn tçm caïch âãø láúy quaí chuäúi, nhæng quaí chuäúi
laûi treo quaï cao âäúi våïi noï. ÅÍ caûnh cæía säø, coï âàût mäüt caïi häüp âãø con khè coï
thãø treìo lãn. Con khè coï thãø thæûc hiãûn caïc âäüng taïc nhæ sau : bæåïc âi trong
phoìng, nhaíy lãn häüp, di chuyãøn caïi häüp (nãúu con khè âæïng caûnh caïi häüp), vaì
Ngæî nghéa cuía chæång trçnh Prolog 49
våïi láúy quaí chuäúi nãúu noï âang âæïng trãn häüp âàût âuïng phêa dæåïi quaí chuäúi.
Cáu hoíi âàût ra laì con khè coï àn âæåüc quaí chuäúi hay khäng ?
Trong láûp trçnh, váún âãö quan troüng laì laìm sao biãøu diãùn âæåüc baìi toaïn
phuì håüp våïi ngän ngæî âang sæí duûng. Træåìng håüp cuía chuïng ta coï thãø nghé
âãún traûng thaïi cuía con khè coï thãø biãún âäøi theo thåìi gian. Traûng thaïi hiãûn
haình âæåüc xaïc âënh båíi vë trê cuía caïc âäúi tæåüng. Chàóng haûn, traûng thaïi ban
âáöu cuía con khè âæåüc xaïc âënh båíi :
(1) Con khè âang åí træåïc cæía (to the door).
(2) Con khè âang åí trãn saìn nhaì (on the floor).
(3) Caïi häüp âang åí caûnh cæía säø (to the window).
(4) Con khè chæa láúy âæåüc quaí chuäúi (not have).
Ta coï thãø nhoïm bäún thäng tin trãn thaình mäüt âäúi tæåüng coï cáúu truïc duy
nháút. Goüi state laì haìm tæí maì ta læûa choün âãø nhoïm caïc thaình pháön cuía âäúi
tæåüng. Hçnh 2.9. trçnh baìy caïch biãøu diãùn traûng thaïi âáöu laì mäüt tæåüng coï cáúu
truïc.
state
Hçnh III.2. Traûng thaïi âáöu cuía con khè laì mäüt âäúi tæåüng coï cáúu truïc
gäöm bäún thaình pháön : vë trê nàòm ngang, vë trê thàóng âæïng cuía con khè,
vë trê cuía caïi häüp vaì mäüt chè dáùn cho biãút con khè âaî láúy âæåüc quaí chuäúi chæa.
State1 State2
Movement
Hçnh III.3. Di chuyãøn traûng thaïi.
Quy æåïc state1 laì traûng thaïi træåïc khi di chuyãøn, M laì di chuyãøn âaî thæûc
hiãûn, vaì state2 laì traûng thaïi sau khi di chuyãøn. Âäüng taïc «nàõm láúy quaí
chuäúi» våïi âiãöu kiãûn âáöu cáön thiãút âæåüc âënh nghéa båíi mãûnh âãö coï näüi dung :
«sau khi di chuyãøn, con khè âaî láúy âæåüc quaí chuäúi, vaì noï âang âæïng trãn caïi
häüp, åí giæîa càn phoìng». Mãûnh âãö âæåüc viãút trong Prolog nhæ sau :
displacement(
state(tothecenter, onthebox, tothecenter, nothave), % træåïc khi di
chuyãøn
grab, % di chuyãøn
state(tothecenter, onthebox, tothecenter, possessing). % sau khi di
chuyãøn
Mäüt caïch tæång tæû, ta coï thãø diãùn taí di chuyãøn cuía con khè trãn saìn nhaì
tæì mäüt vë trê nàòm ngang P1 báút kyì naìo âoï âãún mäüt vë trê måïi P2. Viãûc di
chuyãøn cuía con khè laì âäüc láûp våïi vë trê cuía caïi häüp, vaì âäüc láûp våïi sæû kiãûn con
khè âaî láúy âæåüc quaí chuäúi hay laì chæa :
displacement(
state(P1, onthefloor, G, H),
walking(P1, P2), % di chuyãøn tæì P1 âãún P2
state(P2, onthefloor, G, H).
Mãûnh âãö trãn âáy coï ráút nhiãöu nghéa :
• Di chuyãøn âaî thæûc hiãûn laì «âi tæì P1 âãún P2».
Ngæî nghéa cuía chæång trçnh Prolog 51
• Con khè åí trãn saìn nhaì træåïc vaì sau khi di chuyãøn.
• Vë trê häüp laì G khäng thay âäøi sau khi di chuyãøn.
• Quaí chuäúi váùn åí vë trê cuî træåïc vaì sau khi di chuyãøn
(chæa bë con khè láúy âi).
Mãûnh âãö naìy âàûc træng cho mäüt táûp håüp âáöy âuí caïc âäüng taïc vç coï thãø aïp
duûng cho báút kyì mäüt tçnh huäúng naìo tæång æïng våïi traûng thaïi âaî chè ra træåïc
khi di chuyãøn. Ngæåìi ta goüi caïc mãûnh âãö kiãøu naìy laì mäüt så âäö di chuyãøn.
Hai kiãøu haình âäüng khaïc laì «âáøy» vaì «treìo» cuîng âæåüc âàûc træng mäüt
caïch tæång tæû.
displacement
M
S1 S2 S3 … Sn
couldtake couldtake possessing
Cáu hoíi âàût ra cho baìi toaïn seî laì «Xuáút phaït tæì vë trê âáöu S, con khè coï
thãø láúy âæåüc quaí chuäúi khäng ?» våïi vë tæì sau âáy :
couldtake(S)
våïi tham âäúi S laì mäüt traûng thaïi chè vë trê cuía con khè. Chæång trçnh xáy
dæûng cho vë tæì naìy dæûa trãn hai quan saït sau âáy :
(1) Våïi mäùi traûng thaïi S maì con khè âaî láúy âæåüc quaí chuäúi, vë tæì
couldtake coï giaï trë true, khäng cáön mäüt di chuyãøn naìo khaïc næîa. Âiãöu
naìy tæång æïng våïi sæû kiãûn :
couldtake(state(_, _, _, possessing)).
(2) Trong caïc træåìng håüp khaïc, cáön thæûc hiãûn mäüt hoàûc nhiãöu di chuyãøn.
Xuáút phaït tæì mäüt traûng thaïi S1, con khè coï thãø láúy âæåüc quaí chuäúi
nãúu täön taûi mäüt säú láön di chuyãøn M naìo âoï tæì S1 âãún mäüt traûng thaïi
S2 sao cho trong traûng thaïi S2, con khè coï thãø láúy âæåüc quaí chuäúi.
Ta coï mãûnh âãö sau :
couldtake(S1) :-
displacement(S1, M, S2),
couldtake(S2).
Vë tæì couldtake coï daûng âãû quy, tæång tæû våïi quan hãû ancestor âaî xeït åí
âáöu chæång.
52 Láûp trçnh lägich trong Prolog
displacement(
state(tothecenter, onthebox, tothecenter, nothave),
grab, % våïi láúy quaí chuäúi
state(tothecenter, onthebox, tothecenter, possessing)).
displacement(
state(P, onthefloor, P, H),
climbing, % treìo lãn häüp
state(P, onthebox, P, H)).
displacement(
state(P1, onthefloor, P1, H),
pushing(P1, P2), % âáøy caïi häüp tæì P1 âãún P2
state(P2, onthefloor, P2, H)).
displacement(
state(P1, onthefloor, G, H),
walking(P1, P2), % di chuyãøn tæì P1 âãún P2
state(P2, onthefloor, G, H)).
pushing(tothewindow, tothecenter).
walking(tothedoor, tothewindow).
% couldtake(state) : con khè coï thãø láúy âæåüc quaí chuäúi trong state
couldtake(state(_, _, _, possessing)). % træåìng håüp 1 : con khè âaî coï quaí chuäúi
couldtake(State1) :- % træåìng håüp 2 : cáön phaíi haình âäüng
displacement(State1, Move, State2), % haình âäüng
couldtake(State2). % láúy quaí chuäúi
Chæång trçnh trãn âáy âaî âæåüc phaït triãøn mäüt caïch phi thuí tuûc. Âãø xeït
tênh thuí tuûc cuía chæång trçnh, ta âàût ra cáu hoíi sau âáy :
?- couldtake(state(tothedoor, onthefloor, tothewindow, nothave)).
Yes
Âãø coï cáu traí låìi, Prolog phaíi thoaí maîn mäüt danh saïch caïc âêch theo ngæî
nghéa thuí tuûc. Âoï laì quaï trçnh tçm kiãúm cho con khè mäüt di chuyãøn håüp lyï
trong moüi di chuyãøn coï thãø. Âäi khi, quaï trçnh naìy seî dáùn âãún mäüt ngoî cuût,
âãø thoaït ra, cáön phaíi quay lui. Cáu hoíi trãn cáön quay lui mäüt láön. Caïc di
chuyãøn håüp lyï tiãúp theo âæåüc tçm tháúy ngay do caïc mãûnh âãö liãn quan âãún
quan hãû displacement coï màût trong chæång trçnh, phuì håüp våïi tçnh huäúng.
Ngæî nghéa cuía chæång trçnh Prolog 53
Tuy nhiãn, váùn coï thãø xaíy ra khaí nàng caïc di chuyãøn khäng håüp lyï. Con
khè âi tåïi âi lui maîi maì khäng chaûm âæåüc caïi häüp, hoàûc khäng coï âêch thæûc
sæû. Trong vê duû trãn, ta âaî æu tiãn quaï trçnh so khåïp caïc mãûnh âãö âãø dáùn
âãún thaình cäng.
Hçnh III.5. Låìi giaíi cuía baìi toaïn con khè vaì quaí chuäúi.
Quaï trçnh tçm kiãúm bàõt âáöu tæì nuït trãn cuìng vaì tiãúp tuûc xuäúng dæåïi.
Caïc pheïp thæí thæûc hiãûn láön læåüt tæì traïi qua phaíi.
Chè xaíy ra mäüt láön quay lui maì thäi.
54 Láûp trçnh lägich trong Prolog
III.3. Sàõp âàût thæï tæû caïc mãûnh âãö vaì caïc âêch
Trong nhæîng træåìng håüp nhæ váûy, Prolog khäng thãø xoaï mäüt âêch vç
Prolog cäú gàõng âæa ra mäüt cáu traí låìi trong khi âang âi theo mäüt con âæåìng
xáúu (khäng dáùn âãún thaình cäng).
Cáu hoíi chuïng ta muäún âàût ra laì : liãûu chuïng ta coï thãø thay âäøi chæång
trçnh sao cho coï thãø dæû phoìng træåïc nguy cå bë quáøn ? Coï phaíi chuïng ta luän
luän bë phuû thuäüc vaìo sæû sàõp âàût thæï tæû âuïng âàõn cuía caïc mãûnh âãö vaì caïc
âêch ? Roî raìng ràòng caïc chæång trçnh låïn seî tråí nãn dãù sai soït nãúu phaíi dæûa
trãn mäüt thæï tæû naìo âoï cuía caïc mãûnh âãö vaì caïc âêch. Täön taûi nhiãöu phæång
phaïp khaïc cho pheïp loaûi boí caïc voìng làûp vä haûn, täøng quaït hån vaì âaïng tin
cáûy hån so våïi phæång phaïp sàõp âàût thæï tæû. Sau âáy, chuïng ta seî sæí duûng
thæåìng xuyãn nhæîng phæång phaïp naìy trong viãûc tçm kiãúm caïc con âæåìng,
håüp giaíi caïc baìi toaïn vaì duyãût caïc âäö thë.
III.3.2. Thay âäøi thæï tæû mãûnh âãö vaì âêch trong chæång trçnh
Ngay caïc vê duû åí âáöu chæång, ta âaî tháúy nguy cåí xaíy ra caïc voìng làûp vä
haûn. Chæång trçnh mä taí quan hãû täø tiãn :
ancestor(X, Z) :-
parent(X, Z).
ancestor(X, Z) :-
parent(X, Y),
ancestor(Y, Z).
Ta haîy xeït mäüt säú biãún thãø cuía chæång trçnh naìy. Vãö màût khai baïo, táút caí
caïc chæång trçnh laì tæång âæång, nhæng vãö màût thuí tuûc, chuïng seî khaïc
nhau. Tham khaío ngæî nghéa khai baïo cuía Prolog, khäng aính hæåíng âãún
nghéa khai baïo, ta coï thãø thay âäøi nhæ sau :
(1) Thæï tæû caïc mãûnh âãö trong mäüt chæång trçnh, vaì
(2) Thæï tæû caïc âêch bãn trong thán cuía caïc mãûnh âãö.
Thuí tuûc ancestor trãn âáy gäöm hai mãûnh âãö, âuäi mãûnh âãö thæï nháút coï
mäüt âêch con vaì âuäi mãûnh âãö thæï hai coï hai âêch con. Nhæ váûy chæång trçnh
seî coï bäún biãún thãø (=1×2×2) maì caí bäún âãöu coï cuìng nghéa khai baïo. Ta nháûn
âæåüc nhæ sau :
(1) Âaío thæï tæû caïc mãûnh âãö, vaì
(2) Âaío thæï tæû caïc âêch cho mäùi sàõp âàût thæï tæû caïc mãûnh âãö.
Ngæî nghéa cuía chæång trçnh Prolog 57
Hçnh dæåïi âáy mä taí bäún thuí tuûc anc1, anc2, anc3, anc4 :
% Thuí tuûc gäúc
anc1(X, Z) :-
parent(X, Z).
anc1 (X, Z) :-
parent(X, Y),
anc1 (Y, Z).
% Biãún thãø a : hoaïn âäøi caïc mãûnh âãö
anc2 (X, Z) :-
parent(X, Y),
anc2 (Y, Z).
anc2(X, Z) :-
parent(X, Z).
% Biãún thãø b : hoaïn âäøi caïc âêch cuía mãûnh âãö thæï hai
anc3(X, Z) :-
parent(X, Z).
anc3 (X, Z) :-
anc3 (X, Y),
parent(Y, Z).
% Biãún thãø c : hoaïn âäøi caïc âêch vaì caïc mãûnh âãö
anc4 (X, Z) :-
anc4 (X, Y),
parent(Y, Z).
anc4(X, Z) :-
parent(X, Z).
% Caïc cáu hoíi âæåüc âàût ra láön læåüt nhæ sau :
?- anc1(tom, pat).
-> Yes
?- anc2(tom, pat).
-> Yes
?- anc3(tom, pat).
-> Yes
?- anc4(tom, pat).
ERR 211 Not enough local stack
58 Láûp trçnh lägich trong Prolog
Hçnh III.6. Biãún thãø a cuía quan hãû täø tiãn traí låìi cáu hoíi
“Tom coï phaíi laì mäüt täø tiãn cuía Pat ?”
Trong træåìng håüp cuäúi cuìng, Prolog khäng thãø tçm ra cáu traí låìi. Do bë
quáøn vä haûn nãn Prolog thäng baïo “khäng âuí bäü nhåï”. Hçnh 2.4. mä taí quaï
trçnh thæûc hiãûn cuía anc1 (træåïc âáy laì ancestor) cho cuìng mäüt cáu hoíi.
Hçnh 2.13 (a, b, c) mä taí quaï trçnh thæûc hiãûn cuía anc2, anc3 vaì anc4. Ta
tháúy anc4 khäng coï hy voüng vaì anc2 keïm hiãûu quaí hån so våïi anc1 do thæûc
hiãûn nhiãöu láön tçm kiãúm vaì quay lui hån trong cáy.
Ngæî nghéa cuía chæång trçnh Prolog 59
So saïnh caïc quaï trçnh so khåïp trong caïc hçnh veî, ta tháúy ràòng cáön khai
baïo caïc mãûnh âãö âuí âån giaín khi giaíi caïc baìi toaïn. Âäúi våïi baìi toaïn quan hãû
täø tiãn, caí bäún biãún thãø âãöu dæûa trãn hai yï :
• kiãøm tra nãúu hai tham âäúi cuía quan hãû täø tiãn thoaí maîn quan hãû parent.
• giai âoaûn phæïc taûp nháút laì tçm ai âoï “giæîa” nhæîng ngæåìi laì parent hay
ancestor.
Hçnh III.7. Biãún thãø b cuía quan hãû täø tiãn traí låìi cáu hoíi
“Tom coï phaíi laì mäüt täø tiãn cuía Pat ?”
anc4(tom, Y’’’)
parent(Y’’’, Y’‘)
parent(Y’‘, Y’)
parent(Y’, pat)
Hçnh III.8. Biãún thãø c cuía quan hãû täø tiãn traí låìi cáu hoíi
“Tom coï phaíi laì mäüt täø tiãn cuía Pat ?”
60 Láûp trçnh lägich trong Prolog
Trong säú bäún biãún thãø cuía quan hãû ancestor, chè coï anc1 laì thæûc hiãûn quaï
trçnh so khåïp âån giaín nháút. Trong khi âoï, anc4 bàõt âáöu quaï trçnh khoï khàn
nháút. Coìn anc2 vaì anc3 nàòm giæîa hai thaïi cæûc naìy. Duì ta coï xem xeït chi tiãút
caïc quaï trçnh thæûc hiãûn thãú naìo âi chàng næîa, thç anc1 váùn laì luáût âån giaín
nháút. Ngæåìi ta khuyãn nãn sæí duûng caïch naìy khi láûp trçnh.
Ta khäng cáön so saïnh bäún biãún thãø maì xem xeït våïi kiãøu cáu hoíi naìo thç
mäùi biãún thãø dáùn âãún thaình cäng hay tháút baûi. Ta dãù nháûn tháúy ràòng caí hai
thuí tuûc anc1 vaì anc2 âãöu coï khaí nàng âæa ra cáu traí låìi cho moüi kiãøu cáu
hoíi. Coìn anc3 thç khäng chàõc chàõn. Chàóng haûn cáu hoíi sau âáy gáy ra tháút
baûi :
anc3(liz, jim)
ERR 212 Not enough global stack
vç dáùn âãún nhæîng låìi goüi âãû quy vä haûn. Nhæ váûy, ta khäng thãø xem anc3 laì
âuïng âàõn vãö màût thuí tuûc.
• Viãûc âàût caïc cáu hoíi trãn caïc quan hãû tæång tæû viãûc váún tin mäüt cå såí dæî
liãûu. Prolog traí låìi cáu hoíi bàòng caïch liãût kã táûp håüp caïc âäúi tæåüng laìm
thoaí maîn cáu hoíi naìy.
• Trong Prolog, khi mäüt âäúi tæåüng laìm thoaí maîn mäüt cáu hoíi thç viãûc traí låìi
cáu hoíi luän luän laì mäüt quaï trçnh phæïc taûp sæí duûng suy diãùn lägich, khai
thaïc caïc khaí nàng khaïc nhau, vaì cå chãú quay lui. Prolog tiãún haình tæû
âäüng quaï trçnh naìy vaì vãö nguyãn tàõc, NSD coï thãø hiãøu âæåüc.
• Ngæåìi ta phán biãût nghéa khai baïo vaì nghéa thuí tuûc khi láûp trçnh. Mäüt
chæång trçnh Prolog thæåìng coï nghéa khai baïo laì chuí yãúu. Tuy nhiãn,
ngæåìi ta váùn tçm tháúy nghéa thuí tuûc trong mäüt säú chæång trçnh Prolog.
• Theo nghéa thuí tuûc, chæång trçnh Prolog thæûc hiãûn quaï trçnh tçm kiãúm, so
khåïp vaì quay lui.
• Ngæî nghéa khai baïo cuía Prolog xaïc âënh nãúu mäüt âêch laì âuïng âäúi våïi mäüt
chæång trçnh âaî cho, tæång æïng våïi raìng buäüc cuía caïc biãún.
• Ngæåìi ta quy æåïc viãút pheïp giao (and) cuía hai âêch bàòng caïch âàût mäüt dáúu
pháøy åí giæîa chuïng, pheïp hoàûc (or) båíi mäüt dáúu cháúm pháøy.
• Ngæî nghéa thuí tuûc cuía Prolog âæåüc thãø hiãûn båíi mäüt thuí tuûc tçm kiãúm laìm
thoaí maîn mäüt danh saïch caïc âêch tæì mäüt chæång trçnh âaî cho. Nãúu tçm
kiãúm thoaí maîn, Prolog traí vãö caïc raìng buäüc caïc biãún tæång æïng. Nãúu taûi
mäüt bæåïc naìo âoï bë tháút baûi, thuí tuûc naìy cho pheïp tæû âäüng quay lui
(backtracking) âãø tçm kiãúm tçm caïc khaí nàng khaïc coï thãø dáùn âãún thaình
cäng.
• Nghéa khai baïo cuía caïc chæång trçnh thuáön Prolog khäng phuû thuäüc sæû
sàõp âàût caïc mãûnh âãö, cuîng nhæ khäng phuû thuäüc sæû sàõp âàût caïc âêch bãn
trong caïc mãûnh âãö.
• Nghéa thuí tuûc phuû thuäüc thæï tæû caïc âêch vaì caïc mãûnh âãö. Thæï tæû sàõp âàût
naìy coï thãø aính hæåíng âãún tênh hiãûu quaí chaûy chæång trçnh, vaì coï thãø dáùn
âãún nhæîng låìi goüi âãû quy vä haûn.
• Cho træåïc mäüt khai baïo âuïng, coï khaí nàng laìm täúi æu hiãûu quaí váûn haình
cuía hãû thäúng bàòng caïch thay âäøi thæï tæû caïc mãûnh âãö, maì váùn âaím baío
tênh âuïng âàõn vãö màût khai baïo. Sæû sàõp âàût laûi thæï tæû caïc âêch vaì caïc
mãûnh âãö laì mäüt trong nhæîng phæång phaïp nhàòm traïnh caïc voìng làûp quáøn
vä haûn.
62 Láûp trçnh lägich trong Prolog
• Coìn coï nhæîng kyî thuáût khaïc täøng quaït hån âãø traïnh caïc voìng làûp quáøn vä
haûn, vaì laìm cho chæång trçnh váûn haình âaïng tin cáûy hån.
Haîy so saïnh caïc quaï trçnh mä phoíng cáu hoíi trãn vaì caïc âêch dæåïi âáy :
?- dack( X ), thick( X ).
5. Âiãöu gç xaíy ra khi yãu cáöu Prolog traí låìi cáu hoíi sau âáy :
?- X = f( X ).
Haîy cho biãút caïch Prolog traí låìi caïc cáu hoíi sau âáy (khi coï nhiãöu cáu traí låìi
coï thãø, haîy âæa ra êt nháút hai cáu traí låìi) ?
a) ?- f( s( 1 ) , A ).
64 Láûp trçnh lägich trong Prolog
b) ?- f( s( s( 1 ) ) , two ).
c) ?- f( s( s( s( s( s( s( 1 ) ) ) ) ) ), C ).
d) ?- f( D, three ).
8. Cho caïc vë tæì p, a1, a2, a3, a4 âæåüc âënh nghéa båíi caïc mãûnh âãö sau âáy :
p(a, b).
p(b, c b).
a1(X, Y) :- p(X, Y).
a1(X, Y) :- p(X, Z), a1(Z, Y).
a2(X, Y) :- p(X, Y).
a2(X, Y) :- a2(Z, Y), p(X, Z).
a3(X, Y) :- p(X, Z), a3(Z, Y).
a3(X, Y) :- p(X, Y).
a4(X, Y) :- a4(Z, Y), p(X, Z).
a4(X, Y) :- p(X, Y).
a) Veî cáy håüp giaíi SLD coï caïc gäúc laì a1(a, X), a2(a, X), a3(a, X), a4(a, X) ?
I. Säú hoüc
I.1. Caïc pheïp toaïn säú hoüc
Nhæ âaî biãút, Prolog laì ngän ngæî chuí yãúu duìng âãø xæí lyï kyï hiãûu, khäng
thêch håüp âãø tênh toaïn säú. Do váûy, caïc phæång tiãûn tênh toaïn trong háöu hãút
caïc hãû thäúng Prolog âãöu ráút haûn chãú. Sau âáy laì baíng caïc pheïp toaïn säú hoüc
chuáøn (standard arithmetic operations) cuía Prolog :
65
66 Láûp trçnh lägich trong Prolog
Tham âäúi bãn traïi pheïp toaïn is laì mäüt âäúi tæåüng så cáúp. Tham âäúi bãn
phaíi laì mäüt biãøu thæïc säú hoüc âæåüc håüp thaình tæì caïc pheïp toaïn säú hoüc, caïc säú
vaì caïc biãún. Vç pheïp toaïn is seî khåíi âäüng viãûc tênh toaïn, cho nãn khi thæûc
hiãûn âêch naìy, táút caí caïc biãún cáön phaíi âæåüc raìng buäüc våïi caïc giaï trë säú.
Prolog so khåïp thaình cäng nãúu Number khåïp âæåüc våïi Expr. Nãúu Expr laì kiãøu
thæûc (float) thç âæåüc xem nhæ mäüt soï nguyãn.
Vê duû I.1 :
?- X is 3*4.
X = 12
Yes
?- is(X, 40+50).
X = 90
Yes
?- 1.0 is sin(pi/2).
No % sai do sin(pi/2) âæåüc laìm troìn thaình 1
?- 1.0 is float(sin(pi/2)).
Yes
Trong Prolog, caïc pheïp toaïn säú hoüc keïo theo sæû tênh toaïn trãn caïc dæî liãûu.
Âãø thæûc hiãûn caïc pheïp toaïn säú hoüc, cáön biãút caïch goüi duìng theo kiãøu Prolog
maì khäng thãø goüi træûc tiãúp ngay âæåüc nhæ trong caïc ngän ngæî láûp trçnh
mãûnh lãûnh.
Chàóng haûn, nãúu NSD cáön cäüng hai säú 1 vaì 2 maì laûi viãút nhæ sau :
?- X = 1 + 2
thç Prolog seî traí låìi theo kiãøu cuía Prolog :
X=1+2
maì khäng phaíi laì X = 3 nhæ mong muäún. Lyï do ráút âån giaín : biãøu thæïc
X = 1 + 2 chè laì mäüt haûng cuía Prolog maì haìm tæí chênh laì +, coìn 1 vaì 2 laì caïc
tham âäúi cuía noï. Khäng coï gç trong âêch træåïc noï âãø Prolog tiãún haình pheïp
cäüng. Sau âáy laì mäüt säú vê duû :
?- X = 1 + 1 + 1.
X = 1 + 1 + 1 (ou X = +(+(1, 1), 1)).
Âãø Prolog tiãún haình tênh toaïn trãn caïc pheïp toaïn säú hoüc, sæí duûng pheïp
toaïn is nhæ sau :
?- X is 1 + 2.
X=3
Caïc pheïp toaïn vaì säú hoüc 67
Pheïp cäüng thæûc hiãûn âæåüc laì nhåì mäüt thuí tuûc âàûc biãût kãút håüp våïi pheïp
toaïn +. Nhæîng thuí tuûc nhæ váûy âæåüc goüi laì thuí tuûc thæåìng truï (built-in
procedures).
?- X = 1 + 1 + 1, Y is X.
X = 1 + 1 + 1, Y = 3.
?- X is 1 + 1 + a.
ERROR: Arithmetic: `a/0' is not a function (sai do a khäng phaíi laì haìm säú)
?- X is 1 + 1 + Z.
ERROR: Arguments are not sufficiently instantiated (sai do a khäng phaíi laì
säú)
?- Z = 2, X is 1 + 1 + Z.
Z=2
X=4
Âäü æu tiãn cuía caïc pheïp toaïn säú hoüc tiãön âënh cuía Prolog cuîng laì âäü æu
tiãn thoaí maîn tênh cháút kãút håüp trong toaïn hoüc. Caïc càûp dáúu ngoàûc coï thãø
laìm thay âäøi thæï tæû âäü æu tiãn giæîa caïc pheïp toaïn. Chuï yï ràòng +, -, *, / vaì //
âæåüc âënh nghéa nhæ laì yfx, coï nghéa laì viãûc tênh toaïn âæåüc thæûc hiãûn tæì traïi
sang phaíi. Vê duû, biãøu thæïc :
X is 5 -2 – 1
âæåüc giaíi thêch nhæ laì :
X is ( 5 -2 ) - 1
Do âoï :
?- X is 5 -2 - 1.
X=2
Yes
?- X = 5 -2 - 1.
X = 5-2-1
Yes
Caïc pheïp so saïnh giaï trë säú hoüc trong Prolog âæåüc thæûc hiãûn theo nghéa
Toaïn hoüc thäng thæåìng. Chàóng haûn, ta cáön so saïnh nãúu têch cuía 277 våïi 37
laì låïn hån 10000 våïi âêch sau :
?- 277 * 37 > 10000.
Yes
68 Láûp trçnh lägich trong Prolog
Báy giåì giaí sæí ta coï quan hãû birth, cho pheïp liãn hãû mäüt ngæåìi våïi ngaìy
thaïng nàm sinh cuía ngæåìi âoï. Ta coï thãø tçm âæåüc tãn cuía nhæîng ngæåìi sinh
ra giæîa nàm 1950 vaì nàm 1960 (kãø caí hai nàm naìy) bàòng caïch âàût cáu hoíi :
?- birth( Name, Year ), Year >= 1950, Year <= 1960.
% kãút quaí traí vãö laì tãn nhæîng ngæåìi sinh ra trong khoaíng 1950 - 1960
Yes
Prolog coï sàôn caïc haìm säú hoüc nhæ : sin, cos, tan, atan, sqrt, pi, e, exp, log,
...
Vê duû I.2 :
?- X is exp(10).
X = 22026.5
Yes
?- X is sqrt(9).
X=3
Yes
7 ?- X is abs(1.99).
X = 1.99
Yes
?- X is pi.
X = 3.14159
Yes
ngoaìi, nhæng thæûc cháút, caïc biãøu thæïc âæåüc biãøu diãùn bãn trong váùn åí daûng
tiãön täú, theo quy æåïc viãút caïc haûng trong mäüt mãûnh âãö.
+
* *
2 a b c
háûu täú chè coï mäüt tham âäúi âæåüc âàût træåïc (hoàûc âàût sau tæång æïng) dáúu pheïp
toaïn f.
Coï ba nhoïm kiãøu pheïp toaïn trong Prolog nhæ sau :
Caïc pheïp toaïn Khäng kãút håüp Kãút håüp phaíi Kãút håüp traïi
Trung täú xfx xfy yfx
Tiãön täú fx fy
Háûu täú xf yf
- -
- c a -
Tênh dãù âoüc cuía mäüt chæång trçnh tuyì thuäüc vaìo caïch sæí duûng caïc pheïp
toaïn. Trong caïc chæång trçnh Prolog, nhæîng mãûnh âãö sæí duûng pheïp toaïn måïi
do ngæåìi duìng âënh nghéa thæåìng âæåüc goüi laì caïc chè dáùn hay âënh hæåïng
(directive). Caïc chè dáùn phaíi xuáút hiãûn træåïc khi mäüt pheïp toaïn måïi âæåüc sæí
duûng âãún trong mäüt mãûnh âãö, coï daûng nhæ sau :
:- op(Âäü æu tiãn, Caïch kãút håüp, Tãn pheïp toaïn).
Chàóng haûn ngæåìi ta âënh nghéa pheïp toaïn is nhåì chè dáùn :
:- op( 600, xfx, is ).
Chè dáùn naìy baïo cho Prolog biãút ràòng is seî âæåüc sæí duûng nhæ laì mäüt pheïp
toaïn coï âäü æu tiãn laì 600, coìn kyï hiãûu âàûc taí xfx chè âënh âáy laì mäüt pheïp
toaïn trung täú. YÏ nghéa cuía xfx nhæ sau : f laì dáúu pheïp toaïn âæåüc âàût åí giæîa,
coìn x laì tham âäúi âæåüc âàût hai bãn dáúu pheïp toaïn.
Viãûc âënh nghéa mäüt pheïp toaïn khäng keïo theo mäüt haình âäüng (action)
hoàûc mäüt thao taïc (opration) naìo. Vãö nguyãn lyï, khäng mäüt thao taïc naìo trãn
dæî liãûu âæåüc kãút håüp våïi mäüt pheïp toaïn (træì mäüt vaìi træåìng håüp hiãúm gàûp âàûc
biãût, nhæ caïc pheïp toaïn säú hoüc). Tæång tæû nhæ moüi haìm tæí, caïc pheïp toaïn chè
âæåüc duìng âãø cáúu truïc caïc haìm tæí, maì khäng keïo theo mäüt thao taïc naìo trãn
caïc dæî liãûu, dáùu ràòng tãn goüi «pheïp toaïn» coï thãø gåüi lãn vai troì hoaût âäüng.
72 Láûp trçnh lägich trong Prolog
Prolog cung cáúp sàôn mäüt säú pheïp toaïn chuáøn. Nhæîng pheïp toaïn tiãön âënh
nghéa naìy thay âäøi tuìy theo phiãn baín Prolog. Hçnh 3.5 dæåïi âáy trçnh baìy
mäüt säú pheïp toaïn chuáøn tiãön âënh nghéa cuía Prolog. Chuï yï ràòng cuìng mäüt
mãûnh âãö coï thãø âënh nghéa nhiãöu pheïp toaïn, miãùn laì chuïng cuìng kiãøu vaì
cuìng âäü æu tiãn. Caïc tãn pheïp toaïn âæåüc viãút trong mäüt danh saïch.
Caïc pheïp toaïn tiãön âënh nghéa trong Prolog nhæ sau :
Hçnh 3.5. Caïc pheïp toaïn tiãön âënh nghéa trong Prolog.
Âãø minh hoaû, ta xeït vê duû viãút mäüt chæång trçnh xæí lyï caïc biãøu thæïc lägich
(boolean). Giaí sæí ta cáön biãøu diãùn mäüt trong caïc âënh lyï tæång âæång cuía
Morgan, âæåüc viãút dæåïi daûng toaïn hoüc nhæ sau :
∼ ( A & G ) <===> ~ A ∨ ∼ B
Trong Prolog, mãûnh âãö trãn phaíi âæåüc viãút nhæ sau :
equivalent( not ( and( A, B ) ), or(not ( A ), not ( B ) ) ).
Tuy nhiãn, caïch láûp trçnh täút nháút laì thæí tçm caïch baío læu täúi âa sæû giäúng
nhau giæîa caïc kyï hiãûu trong baìi toaïn âaî cho våïi caïc kyï hiãûu âæåüc sæí duûng
trong chæång trçnh..
Caïc pheïp toaïn vaì säú hoüc 73
<===>
~ v
& ~ ~
A B A B
Chuï yï ràòng caïc pheïp toaïn = vaì =:= laì hoaìn toaìn khaïc nhau, chàóng haûn
trong caïc âêch X = Y vaì X =:= Y :
• Âêch X = Y keïo theo viãûc âäöng nháút caïc âäúi tæåüng X vaì Y, nãúu chuïng
âäöng nháút våïi nhau thç coï thãø raìng buäüc mäüt säú biãún naìo âoï trong X vaì
Y.
• Âêch X =:= Y chè gáy ra mäüt pheïp tênh säú hoüc âãø so saïnh maì khäng xaíy
pheïpû raìng buäüc naìo trãn caïc biãún.
Vê duû II.1 :
?- X = Y.
X = _G997
Y = _G997
Yes
?- 1 + 2 =:= 2 + 1.
Yes.
?- 1 + 2 = 2 + 1.
No.
?- 1 + 2 = 1 + 2.
Yes.
?- 1 + X = 1 + 2.
X=2
?- 1 + A = B + 2.
A=2
B=1
?- 1 + 2 =:= 2 + 1.
Yes.
?- 1 + X =:= 1 + 2.
ERROR: Arguments are not sufficiently instantiated (sai do a khäng phaíi laì
säú)
?- 1 + 2 == 1 + 2.
Yes.
?- 1 + 2 == 2 + 1.
No.
?- 1 + X == 1 + 2.
No.
?- 1 + a == 1 + a.
Yes.
Caïc pheïp toaïn vaì säú hoüc 75
1 is sin(pi/2).
Yes
?- 1.0 is sin(pi/2).
No
?- 1.0 is float(sin(pi/2)).
Yes
?- 1.0 =:= sin(pi/2).
Yes
Term1 == Term2 Thaình cäng nãúu Term1 tæång âæång våïi Term2. Mäüt biãún
chè âäöng nháút våïi mäüt biãún cuìng chia seí trong haûng
(sharing variable)
Term1 = Term2 Thaình cäng nãúu Term1 khåïp âæåüc våïi Term2
Term1 =@= Term2 Thaình cäng nãúu Term1 coï cuìng cáúu truïc (structurally
equal) våïi Term2. Tênh coï cuìng cáúu truïc yãúu hån tênh
tæång âæång (equivalence), nhæng laûi maûnh hån pheïp
håüp nháút
Term1 @< Term2 Thaình cäng nãúu Term1 vaì Term2 theo thæï tæû chuáøn cuía
caïc haûng
Term1 @=< Term2 Thaình cäng nãúu hoàûc hai haûng bàòng nhau hoàûc Term1
âæïng træåïc Term2 theo thæï tæû chuáøn cuía caïc haûng
Term1 @> Term2 Thaình cäng nãúu Term1 âæïng sau Term2 theo thæï tæû
chuáøn cuía caïc haûng
Term1 @>= Term2 Thaình cäng nãúu hoàûc hai haûng bàòng nhau both hoàûc
Term1 âæïng sau Term2 theo thæï tæû chuáøn cuía caïc haûng
compare(?Order, Haûng1, Haûng2) Kiãøm tra thæï tæû <, > hoàûc = giæîa hai haûng
76 Láûp trçnh lägich trong Prolog
Vê duû II.2 :
?- free_variables(a(X, b(Y, X), Z), L).
L = [G367, G366, G371]
X = G367
Y = G366
Z = G371
?- a =@= A.
No
?- a =@= B.
No
?- x(A, A) =@= x(B, C).
No
?- x(A, A) =@= x(B, B).
A = _G267
B = _G270
Yes
5 ?- x(A, B) =@= x(C, D).
A = _G267
B = _G268
C = _G270
D = _G271
Yes
?- 3 @< 4.
Yes
?- 3 @< a.
Yes
?- a @< abc6.
Yes
?- abc6 @< t(c, d).
Yes
?- t(c, d) @< t(c, d, X).
X = _G284
Yes
Caïc pheïp toaïn vaì säú hoüc 77
arg(N, Term, X) Thãú biãún X cho tham âäúi thæï N cuía haûng Term
78 Láûp trçnh lägich trong Prolog
Vê duû thuí tuûc âãû quy taûo daîy 10 säú tæû nhiãn chàôn âáöu tiãn nhæ sau : âáöu
tiãn láúy giaï trë 0 âãø khåíi âäüng quaï trçnh. Sau âoï láúy 0 laì giaï trë hiãûn haình âãø
taûo säú tiãúp theo nhåì så âäö làûp : even_succ_nat = even_succ_nat + 2. Quaï
trçnh cæï tiãúp tuûc nhæ váûy cho âãún khi âaî coï âuí 10 säú 0 2 4 6 8 10 12 14 16 18
thç dæìng laûi.
Trong Prolog, mäüt mãûnh âãö âãû quy (âãø taûo så âäö làûp ) laì mãûnh âãö coï chæïa
trong thán (vãú phaíi) êt nháút mäüt láön låìi goüi laûi chênh mãûnh âãö âoï (vãú traïi) :
a(X) :- b(X, Y), a(Y).
Mãûnh âãö a goüi laûi chênh noï ngay trong vãú phaíi. Daûng så âäö làûp nhæ váûy
âæåüc goüi laì âãû quy træûc tiãúp. Âãø khäng xaíy ra låìi goüi vä haûn, cáön coï mäüt mãûnh
âãö laìm âiãöu kiãûn dæìng âàût træåïc mãûnh âãö. Mäùi láön vaìo làûp måïi, âiãöu kiãûn
dæìng seî âæåüc kiãøm tra âãø quyãút âënh xem coï thãø tiãúp tuûc goüi a hay khäng ?
Ta xáy dæûng thuí tuûc even_succ_nat(Num, Count) taûo láön læåüt caïc säú tæû
nhiãn chàôn Num, biãún Count âãø âãúm säú bæåïc làûp. Âiãöu kiãûn dæìng laì
Count=10, ta coï :
even_succ_nat(Num, 10).
Mãûnh âãö làûp âæåüc xáy dæûng nhæ sau :
even_succ_nat(Num, Count) :-
write(Num), write(' '),
Count1 is Count + 1,
Num1 is Num + 2,
even_succ_nat(Num1, Count1).
Nhæ váûy, låìi goüi taûo 10 säú tæû nhiãn chàôn âáöu tiãn seî laì :
?- even_succ_nat(0, 0).
0 2 4 6 8 10 12 14 16 18
Yes
Mäüt caïch khaïc âãø xáy dæûng så âäö làûp âæåüc goüi laì âãû quy khäng træûc tiãúp coï
daûng nhæ sau :
a(X) :- b(X).
b(X) :- c(Y...), a(Z).
Trong så âäö làûp naìy, mãûnh âãö âãû quy a khäng goüi goüi træûc tiãúp âãún a, maì
goüi âãún mäüt mãûnh âãö b khaïc, maì trong b naìy laûi coï låìi goüi âãún a. Âãø khäng
xaíy ra låìi goüi luáøn quáøn vä haûn, trong b cáön thæûc hiãûn caïc tênh toaïn laìm
Caïc pheïp toaïn vaì säú hoüc 81
giaím dáön quaï trçnh làûp træåïc khi goüi laûi mãûnh âãö a (vê duû mãûnh âãö c). Vê duû
så âäö dæåïi âáy seî gáy ra voìng luáøn quáøn vä haûn :
a(X) :- b(X, Y).
b(X, Y) :- a(Z).
Baìi toaïn taûo 10 säú tæû nhiãn chàôn âáöu tiãn âæåüc viãút laûi theo så âäö âãû quy
khäng træûc tiãúp nhæ sau :
a(0).
a(X) :- b(X).
b(X) :- X1 is X - 2, write(X), write(' '), a(X1).
Chæång trçnh naìy khäng goüi « âãû quy » nhæ even_succ_nat. Kãút quaí sau
låìi goüi a(20) laì daîy säú giaím dáön 20 18 16 14 12 10 8 6 4 2.
Vê duû III.2 : Xáy dæûng säú tæû nhiãn (Peano) vaì pheïp cäüng trãn caïc säú tæû nhiãn
/* Âënh nghéa säú tæû nhiãn */
nat(0). % 0 laì mäüt säú tæû nhiãn
nat(s(N)) :- % s(X) cuîng laì mäüt säú tæû nhiãn
nat(N). % nãúu N laì mäüt säú tæû nhiãn
Chàóng haûn säú 5 âæåüc viãút : s(s(s(s(s(zero)))))
/* Âënh nghéa pheïp cäüng */
addi(0, X, X). % luáût 1 : 0 + X = X
addi(X, 0, X). % luáût 2 : X + 0 = X
addi(s(X), Y, s(Z)) :- % luáût 3 : nãúu X + Y = Z thç (X+1) + Y =
(Z+1)
addi(X, Y, Z).
Hoàûc âënh nghéa theo nat(X) nhæ sau :
addi(0, X, X) :- nat(X).
?- addi(X, Y, s(s(s(s(0))))).
X=0
Y = s(s(s(s(0))))
Yes
?- addi(X, s(s(0)), s(s(s(s(s(0)))))).
X = s(s(s(0)))
Yes
?- THREE = s(s(s(0))), FIVE = s(s(s(s(s(0))))), addi(THREE, FIVE, EIGHT).
THREE = s(s(s(0)))
FIVE = s(s(s(s(s(0)))))
82 Láûp trçnh lägich trong Prolog
EIGHT = s(s(s(s(s(s(s(s(0))))))))
Yes
Vê duû III.3 : Tçm æåïc säú chung låïn nháút (GCD: Greatest Common Divisor)
Cho træåïc hai säú nguyãn X vaì Y, ta cáön tênh æåïc säú D vaì USCLN dæûa trãn
ba quy tàõc nhæ sau :
1. Nãúu X = Y, thç D bàòng X.
2. Nãúu X < Y, thç D bàòng USCLN cuía X vaì cuía Y - X.
3. Nãúu X > Y, thç thæûc hiãûn tæång tæû bæåïc 2, bàòng caïch hoaïn vë vai troì X
vaì Y.
Coï thãø dãù daìng tçm âæåüc caïc vê duû minh hoaû sæû hoaût âäüng cuía ba quy tàõc
træåïc âáy. Våïi X =20 vaì Y =25, thç ta nháûn âæåüc D =5 sau mäüt daîy caïc pheïp
træì.
Chæång trçnh Prolog âæåüc xáy dæûng nhæ sau :
gcd( X, X, X ).
gcd( X, Y, D ) :-
X < Y,
Y1 is Y – X,
gcd( X, Y1, D ).
gcd( X, Y, D ) :-
X > Y,
gcd( Y, X, D ).
Âêch cuäúi cuìng trong mãûnh âãö thæï ba trãn âáy coï thãø âæåüc thay thãú båíi :
X1 is X – Y,
gcd( X1, Y, D ).
Kãút quaí chaûy Prolog nhæ sau :
?- gcd( 20, 55, D ).
D=5
Vê duû III.4 : Tênh giai thæìa
fac(0, 1).
fac(N, F) :-
N > 0,
M is N - 1,
fac(M, Fm),
F is N * Fm.
Mãûnh âãö thæï hai coï nghéa ràòng nãúu láön læåüt :
Caïc pheïp toaïn vaì säú hoüc 83
Ta nháûn tháúy thuáût toaïn tênh säú Fibonacci trãn âáy sæí duûng hai láön goüi
âãû quy âaî nhanh choïng laìm âáöy bäü nhåï vaì chè våïi N=21, SWI-prolog phaíi
dæìng laûi âãø thäng baïo läùi.
Vê duû III.6 : Tênh haìm Ackerman
/* Ackerman's function */
ack(0, N, A) :- % Ack(0, n) = n + 1
A is N + 1.
ack(M1, 0, A) :- % Ack(m, n) = Ack(m−1, 1)
M > 0,
M is M - 1,
ack(M, 1, A).
ack(M1, N1, A) :- % Ack(m, n) = Ack(m−1, Ack(m, n−1))
M1 > 0, N1 > 0,
84 Láûp trçnh lägich trong Prolog
M is M - 1, N is N - 1,
ack(M1, N, A1),
ack(M, A1, A).
Vê duû III.7 : Haìm tênh täøng
plus(X, Y, Z) :-
nonvar(X), nonvar(Y),
Z is X + Y.
plus(X, Y, Z) :-
nonvar(Y), nonvar(Z),
X is Z - Y.
plus(X, Y, Z) :-
nonvar(X), nonvar(Z),
Y is Z - X.
Vê duû III.8 : Thuáût toaïn håüp nháút
Sau âáy laì mäüt thuáût toaïn håüp nháút âån giaín cho pheïp xæí lyï træåìng håüp
mäüt biãún naìo âoï âæåüc thay thãú (håüp nháút) båíi mäüt haûng maì haûng naìy laûi coï
chæïa âuïng tãn biãún âoï. Chàóng haûn pheïp håüp nháút X = f(X) laì khäng håüp lãû.
% unify(T1, T2).
unify(X, Y) :- % træåìng håüp 2 biãún
var(X), var(Y), X = Y.
unify(X, Y) :- % træåìng håüp biãún = khäng phaíi biãún
var(X), nonvar(Y), X = Y.
unify(X, Y) :- % træåìng håüp khäng phaíi biãún = biãún
nonvar(X), var(Y), Y = X.
unify(X, Y) :- % nguyãn tæí hay säú = nguyãn tæí hay säú
nonvar(X), nonvar(Y),
atomic(X), atomic(Y),
X = Y.
unify(X, Y) :- % træåìng håüp cáúu truïc = cáúu truïc
nonvar(X), nonvar(Y),
compound(X), compound(Y),
termUnify(X, Y).
termUnify(X, Y) :- % håüp nháút haûng våïi haûng chæïa cáúu truïc
functor(X, F, N),
functor(Y, F, N),
argUnify(N, X, Y).
argUnify(N, X, Y) :- % håüp nháút N tham âäúi cuía X vaì Y
N>0,
Caïc pheïp toaïn vaì säú hoüc 85
argUnify1(N, X, Y),
Ns is N - 1,
argUnify(Ns, X, Y).
argUnify(0, X, Y).
argUnify1(N, X, Y) :- % håüp nháút caïc tham âäúi coï báûc N
arg(N, X, ArgX),
arg(N, Y, ArgY),
unify(ArgX, ArgY).
Vê duû III.9 : Lyï thuyãút säú
Ta tiãúp tuûc xáy dæûng haìm måïi trãn caïc säú tæû nhiãn âaî âæåüc âënh nghéa
trong vê duû 1. Ta xáy dæûng pheïp so saïnh hai säú tæû nhiãn dæûa trãn pheïp cäüng
nhæ sau :
egal(+(X, 0), X). % pheïp cäüng coï tênh giao hoaïn
egal(+(0, X), X).
egal(+(X, s(Y)), s(Z)) :- % X YZ.egal(X+Y, Z) → egal(X+s(Y), s(Z))
egal(+(X, Y), Z).
X = 0+s(s(s(s(0)))) ;
X = 0+s(s(s(s(0)))) ;
No
Våïi âêch egal(X, Y) sau âáy, cáu traí låìi laì vä haûn :
?- egal(X, Y).
X = _G235+0
Y = _G235 ;
X = 0+_G235
Y = _G235 ;
X = _G299+s(0)
Y = s(_G299) ;
X = 0+s(_G302)
Y = s(_G302) ;
X = _G299+s(s(0))
Y = s(s(_G299)) ;
X = 0+s(s(_G309))
Y = s(s(_G309)) ;
X = _G299+s(s(s(0)))
Y = s(s(s(_G299))) ;
X = 0+s(s(s(_G316)))
Y = s(s(s(_G316))) ;
X = _G299+s(s(s(s(0))))
Y = s(s(s(s(_G299)))) ;
X = 0+s(s(s(s(_G323))))
Y = s(s(s(s(_G323)))) ;
X = _G299+s(s(s(s(s(0)))))
Y = s(s(s(s(s(_G299))))) ;
...
X = 0+s(s(s(s(s(s(_G337))))))
Y = s(s(s(s(s(s(_G337)))))) ;
X = _G299+s(s(s(s(s(s(s(0)))))))
Y = s(s(s(s(s(s(s(_G299)))))))
v.v...
Caïc pheïp toaïn vaì säú hoüc 87
fib5
4 3
3 2 2 1
2 1 1 0 1 0
1 0
Hçnh III.1. Biãøu diãùn cáy caïc låìi goüi âãû quy tçm säú Fibonacci
Mäüt säú ngän ngæî mãûnh lãûnh tênh säú Fibonacci sæí duûng cáúu truïc làûp âãø
traïnh tênh âi tênh laûi cuìng mäüt giaï trë. Chæång trçnh Pascal dæåïi âáy duìng
hai biãún phuû x=fib(i) vaì y=fib(i+1) :
{ tênh fib(n) våïi n > 0 }
i:= 1; x:= 1; y:= 0;
while i < n do
begin x:= x + y; y:= x – y end;
Ta viãút laûi chæång trçnh Prolog nhæ sau :
fibo(0, 0).
fibo(N, F) :-
88 Láûp trçnh lägich trong Prolog
N >= 1,
fib1(N, 1, 0, F).
fib1(1, F, _, F).
fib1(N, F2, F1, FN) :-
N > 1,
N1 is N - 1,
F3 is F1 + F2,
fib1(N1, F3, F2, FN).
?- fibo(21, F).
F = 10946
Yes
?- fibo(200, F).
F = 2.80571e+041
Yes
A B
C D
E
Hçnh III.2. Tçm âæåìng âi trong mäüt âäö thë coï âënh hæåïng.
Ta xeït baìi toaïn tçm âæåìng âi giæîa hai âènh cuía âäö thë. Mäùi cung näúi hai
âènh cuía âäö thë biãøu diãùn mäüt quan hãû giæîa hai âènh naìy. Tæì âäö thë trãn, ta
coï thãø viãút caïc mãûnh âãö Prolog biãøu diãùn caïc sæû kiãûn :
arc(a, b).
arc(b, c).
arc(c, e).
arc(c, d).
arc(a, e).
Giaí sæí cáön kiãøm tra coï täön taûi mäüt âæåìng âi giæîa hai nuït a vaì d (khäng
täön taûi âæåìng âi giæîa hai nuït naìy nhæ âaî mä taí), ta viãút mãûnh âãö :
path(a, d).
Caïc pheïp toaïn vaì säú hoüc 89
Ta tháúy âënh nghéa thuí tuûc path(X, Y) tæång tæû thuí tuûc tçm täø tiãn giaïn
tiãúp giæîa hai ngæåìi trong cuìng doìng hoü ancestor(X, Y) âaî xeït træåïc âáy.
?- path(X, Y).
X=a
Y=b;
X=b
Y=c;
...
• Nãúu giæîa hai nuït coï cung näúi chuïng thç âäü daìi âæåìng âi laì 1.
• Goüi L laì âäü daìi âæåìng âi giæîa hai nuït X vaì Y, L1 laì âäü daìi âæåìng âi giæîa
mäüt nuït thæï ba Z vaì Y nãúu täön taûi vaì giaí sæí coï cung näúi X vaì Z, khi âoï
L = L1 + 1.
Goüi expower(X, S) laì haìm tênh giaï trë haìm muî theo X, biãún S laì kãút quaí
gáön âuïng våïi âäü chênh xaïc ε=10-6. Tæì cäng thæïc khai triãøn Max Loren trãn
âáy, ta nháûn tháúy giaï trë cuía haìm muî ex laì täøng vä haûn coï daûng :
5. Viãút haìm Prolog âãø laìm duyãût (tracking/traverse) trãn cáy nhë phán theo
caïc thæï tæû træåïc (reorder), sau (post-order) vaì giæîa (in-order).
Giaí sæí cáy nhë phán tæång æïng våïi biãøu thæïc säú hoüc (5+6)*(3-(2/2)) laì caïc
mãûnh âãö Prolog nhæ sau :
tree(’*’, tree(’+’, leaf(5), leaf(6)), tree(’-’, leaf(3), tree(’/’, leaf(2), leaf(2)))
Kãút quaí duyãût cáy nhæ sau : theo thæï tæû træåïc :
[*, +, 5, 6, -, 3, /, 2, 2]
thæï tæû giæîa :
[5, +, 6, *, 3, -, 2, /, 2]
thæï tæû sau :
[5, 6, +, 3, 2, 2, /, -, *]
6. Viãút laûi haìm taûo 10 säú tæû nhiãn chàôn âáöu tiãn (âaî cho trong pháön âãû quy)
sao cho kãút quaí traí vãö laì daîy säú tàng dáön.
7. Láûp baíng nhán table(R, N) coï säú bë nhán (multiplicator) tæì 1 tråí âi våïi säú
nhán N (multiplier) vaì dæìng laûi khi gàûp säú bë nhán R (kãút quaí R * N).
8. Viãút caïc haìm tênh gáön âuïng giaï trë caïc haìm sau våïi âäü chênh xaïc ε = 10-5 :
π 1 1 1 1
= 1 − + − +... cho âãún khi <ε
4 3 5 7 2n - 1
x2 2 x4 2 4 x6
1+ + × + × × + ... cho âãún khi pháön tæí thæï n
2 3 4 3 5 6
<ε
x2 x3 n x
n
xn
S = 1 - x + - + ... + (-1) + ... cho âãún khi <ε
2! 3! n! n!
x2 x4 x6 x 2n x 2n
S = 1+ + + +...+ +... cho âãún khi < 10−5
2! 4! 6! (2 n)! (2 n)!
9. Trçnh Prolog dæåïi âáy laì mäüt trçnh diãùn dëch (interpreter) cho mäüt ngän
ngæî láûp trçnh âån giaín chè gäöm caïc säú nguyãn int(N), caïc biãún id(X), caïc
haìm fn(X,E), vaì goüi haìm app(E1,E2) :
%% subst(E1, E2, X, V)
94 Láûp trçnh lägich trong Prolog
%% thæûc hiãûn pheïp thãú biãún X båíi biãún V trong E1 âãø traí vãö E2.
subst(int(N), int(N), _, _).
subst(id(X), V, X, V).
subst(id(Y), id(Y), X, _) :-
X \= Y.
subst(fn(X, E), fn(X, E), X, _).
subst(fn(Y, Ea), fn(Y, Eb), X, V) :-
X \= Y,
subst(Ea, Eb, X, V).
subst(app(E1a, E2a), app(E1b, E2b), X, V) :-
subst(E1a, E1b, X, V),
subst(E2a, E2b, X, V).
%% reduce(E, V)
%% thæûc hiãûn pheïp tênh giaï trë cuía E âãø traí vãö V.
reduce(int(N), int(N)).
reduce(fn(X, B), fn(X, B))
reduce(app(E1, E2), V) :-
reduce(E1, fn(X, B)),
reduce(E2, V2),
subst(B, E, X, V2),
reduce(E, V).
Cáu hoíi :
a. Cho biãút caïch trao âäøi tham biãún håüp lãû trong ngän ngæî mä taí trãn
âáy ? Caïch trao âäøi tham biãún naìo thç khäng thãø thæûc hiãûn âæåüc ?
b. Tçm caïch thay âäøi trçnh Prolog trãn âáy âãø coï thãø thæûc hiãûn âæåüc caïc
phæång phaïp trao âäøi tham biãún khaïc nhau.
c. Cho biãút táöm væûc (scope) cuía caïc biãún laì ténh hay âäüng ?
10. Cho vê duû mäüt âäö thë khäng âënh hæåïng dæåïi âáy :
arc(a,b). arc(d,f).
arc(b,c). arc(f,a).
arc(c,d). arc(a,b).
arc(c,e). arc(h,i).
arc(c,g). arc(i,j).
arc(g,f).
Haîy viãút haìm tçm âæåìng âi giæîa hai âènh cuía âäö thë.
CHÆÅNG 4
95
96 Láûp trçnh lägich trong Prolog
Laìm caïch naìo âãø biãøu diãùn danh saïch båíi mäüt âäúi tæåüng Prolog chuáøn ?
Coï hai khaí nàng xaíy ra laì danh saïch coï thãø räùng hoàûc khäng. Nãúu danh saïch
räùng, noï âæåüc viãút dæåïi daûng mäüt nguyãn tæí :
[]
Nãúu danh saïch khaïc räùng, coï thãø xem noï âæåüc cáúu truïc tæì hai thaình pháön
(pair syntax) :
1. Thaình pháön thæï nháút, âæåüc goüi laì âáöu (head) cuía danh saïch.
2. Thaình pháön thæï hai, pháön coìn laûi cuía danh saïch (træì ra pháön âáöu),
âæåüc goüi laì âuäi (tail) cuía danh saïch, cuîng laì mäüt danh saïch.
Trong vê duû trãn thç âáöu laì anne, coìn âuäi laì danh saïch :
[ tennis, tom, skier ]
Noïi chung, âáöu cuía danh saïch coï thãø laì mäüt âäúi tæåüng báút kyì cuía Prolog,
coï thãø laì cáy hoàûc biãún, nhæng âuäi phaíi laì mäüt danh saïch. Hçnh I.1. Biãøu diãùn
daûng cáy cuía danh saïch mä taí cáúu truïc cáy cuía danh saïch âaî cho :
.
âáöu tennis .
tom .
skier []
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 ]
[ X1 | [ ... [ Xn | [ ] ]... ] ] [ X1, ... , Xn ]
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æí lyï danh saïch cuía Prolog
SWI-Prolog coï sàôn mäüt säú vë tæì xæí lyï danh saïch nhæ sau :
Vë tæì YÏ nghéa
append(List1, List2, List3) Gheïp hai danh saïch List1 vaì List2 thaình List3.
Kiãøm tra Elem coï laì pháön tæí cuía danh saïch List hay
member(Elem, List) khäng, nghéa laì Elem håüp nháút âæåüc våïi mäüt trong
caïc pháön tæí cuía List.
Kiãøm tra nãúu pháön tæí Y coï âæïng ngay sau pháön tæí X
nextto(X, Y, List)
trong danh saïch List hay khäng.
Xoaï khoíi danh saïch List1 nhæîng pháön tæí håüp nháút
delete(List1, Elem, List2)
âæåüc våïi Elem âãø traí vãö kãút quaí List2.
Láúy pháön tæí Elem ra khoíi danh saïch List âãø traí vãö
select(Elem, List, Rest) nhæîng pháön tæí coìn laûi trong Rest, coï thãø duìng âãø
cheìn mäüt pháön tæí vaìo danh saïch.
Kiãøm tra pháön tæí thæï Index (tênh tæì 0) cuía danh
nth0(Index, List, Elem)
saïch List coï phaíi laì Elem hay khäng.
Kiãøm tra pháön tæí thæï Index (tênh tæì 1) cuía danh saïch
nth1(Index, List, Elem)
List coï phaíi laì Elem hay khäng.
Kiãøm tra pháön tæí âæïng cuäúi cuìng trong danh saïch
last(List, Elem)
List coï phaíi laì Elem hay khäng.
Nghëch âaío thæï tæû caïc pháön tæí cuía danh saïch List1
reverse(List1, List2)
âãø traí vãö kãút quaí List2.
permutation(List1, List2) Hoaïn vë danh saïch List1 thaình danh saïch List2.
Chuyãøn danh saïch List1 chæïa caïc pháön tæí báút kyì
thaình danh saïch phàóng List2.
flatten(List1, List2)
Vê duû : flatten([a, [b, [c, d], e]], X).
cho kãút quaí X = [a, b, c, d, e].
sumlist(List, Sum) Tênh täøng caïc pháön tæí cuía danh saïch List chæïa toaìn
säú âãø traí vãö kãút quaí Sum.
Nãúu Low vaì High laì caïc säú sao cho Low =< High, thç
numlist(Low, High, List)
traí vãö danh saïch List = [Low, Low+1, ..., High].
Chuï yï mäüt säú vë tæì xæí lyï danh saïch coï thãø sæí duûng cho moüi raìng buäüc, kãø
caí khi caïc tham âäúi âãöu laì biãún.
Trong Prolog, táûp håüp âæåüc biãøu diãùn båíi danh saïch, tuy nhiãn, thæï tæû caïc
pháön tæí trong mäüt táûp håüp laì khäng quan troüng, caïc âäúi tæåüng duì xuáút hiãûn
Cáúu truïc danh saïch 99
nhiãöu láön chè âæåüc xem laì mäüt pháön tæí cuía táûp håüp. Caïc pheïp toaïn vãö danh
saïch coï thãø aïp duûng cho caïc táûp håüp. Âoï laì :
• Kiãøm tra mäüt pháön tæí coï màût trong mäüt danh saïch tæång tæû viãûc kiãøm tra
mäüt pháön tæí coï thuäüc vãö mäüt táûp håüp khäng ?
• Gheïp hai danh saïch âãø nháûn âæåüc mäüt danh saïch thæï ba tæång æïng våïi
pheïp håüp cuía hai táûp håüp.
• Thãm mäüt pháön tæí måïi, hay loaûi boí mäüt pháön tæí.
Prolog coï sàôn mäüt säú vë tæì xæí lyï táûp håüp nhæ sau :
Vë tæì YÏ nghéa
is_set(Set) Kiãøm tra Set coï phaíi laì mäüt táûp håüp hay khäng
Chuyãøn danh saïch List thaình táûp håüp Set giæî
nguyãn thæï tæû caïc pháön tæí cuía List (nãúu List coï caïc
list_to_set(List, Set) pháön tæí truìng nhau thç chè láúy pháön tæí gàûp âáöu
tiãn). Vê duû : list_to_set([a,b,a], X) cho kãút quaí
X = [a,b].
intersection(Set1, Set2, Set3) Pheïp giao cuía hai táûp håüp Set1 vaì Set2 laì Set3.
Traí vãö kãút quaí pheïp hiãûu cuía hai táûp håüp Set vaì
subtract(Set, Delete, Result) Delete laì Result (laì táûp Set sau khi âaî xoaï hãút caïc
pháön tæí cuía Delete coï màût trong âoï).
Traí vãö kãút quaí pheïp håüp cuía hai táûp håüp Set1 vaì
union(Set1, Set2, Set3)
Set2 laì Set3.
Kiãøm tra táûp håüp Subset coï laì táûp håüp con cuía Set
subset(Subset, Set)
hay khäng.
III.1.1. Kiãøm tra mäüt pháön tæí coï màût trong danh saïch
Prolog kiãøm tra mäüt pháön tæí coï màût trong mäüt danh saïch nhæ sau :
member(X, L)
100 Láûp trçnh lägich trong Prolog
trong âoï, X laì mäüt pháön tæí vaì L laì mäüt danh saïch. Âêch member(X, L) âæåüc
thoaí maîn nãúu X xuáút hiãûn trong L. Vê duû :
?- member( b, [ a, b, c ] )
Yes
?- member( b, [ a, [ b, c ] ] )
No
?- member( [ b, c], [ a, [ b, c ] ] )
Yes
Tæì caïc kãút quaí trãn, ta coï thãø giaíi thêch quan hãû member(X, L) nhæ sau :
Pháön tæí X thuäüc danh saïch L nãúu :
1. X laì âáöu cuía L, hoàûc nãúu
2. X laì mäüt pháön tæí cuía âuäi cuía L.
Ta coï thãø viãút hai âiãöu kiãûn trãn thaình hai mãûnh âãö, mãûnh âãö thæï nháút laì
mäüt sæû kiãûn âån giaín, mãûnh âãö thæï hai laì mäüt luáût :
member( X, [ X | Tail ] ).
member( X, [ Head | Tail ] ) :- member( X, Tail ).
hoàûc :
member(X, [X|T]).
member(X, [_|T]) :- member(X, T).
2. Nãúu tham âäúi âáöu tiãn cuía append laì danh saïch khaïc räùng, thç noï gäöm
mäüt âáöu vaì mäüt âuäi nhæ sau
[ X | L1 ]
Kãút quaí pheïp gheïp danh saïch laì danh saïch [ X | L3 ], våïi L3 laì pheïp
gheïp cuía L1 vaì 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 hoaû pheïp gheïp hai danh saïch [ X | L1 ] vaì L2.
[ X | L1 ]
X L1 L2
L3
X L3
[ X | L3 ]
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 nàm, ta coï thãø tçm nhæîng
thaïng âæïng træåïc mäüt thaïng âaî cho, giaí sæí thaïng nàm (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 nàm 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 truïc danh saïch 103
member1( b, [ a, b, c ] )
append( L1, [ b | L2 ], [ a, b, c ] )
Mãûnh âãö 1 cuía append Mãûnh âãö 2 cuía append
So khåïp : So khåïp :
L1 = [ ] L1 = [ X | L1’ ]
[ b | L2 ] = [ a, b, c ] [ b | L2 ] = L2’
[ a, b, c ] = [ X | L3’ ]
Tháút baûi vç b ≠ a
Tæì âoï keïo theo :
X = a, L3’ = [ b, c ]
append( L1’, [ b | L2 ], [ b, c ] )
thaình cäng
Hçnh III.2. Thuí tuûc member1 tçm tuáön tæû mäüt âäúi tæåüng trong danh saïch âaî cho.
So saïnh hai caïch caìi âàût khaïc nhau vãö quan hãû thaình viãn, ta nháûn tháúy
nghéa thuí tuûc trong âënh nghéa member âæåüc thãø hiãûn ráút roî :
Trong member, âãø kiãøm tra pháön tæí X coï màût trong mäüt danh saïch L
khäng,
1. Træåïc tiãn kiãøm tra pháön tæí âáöu cuía L laì âäöng nháút våïi X, nãúu khäng,
2. Kiãøm tra ràòng X coï màût trong pháön âuäi cuía L.
Nhæng trong træåìng håüp âënh nghéa member1, ta tháúy hoaìn toaìn nghéa
khai baïo maì khäng coï nghéa thuí tuûc.
Âãø hiãøu âæåüc caïch member1hoaût âäüng nhæ thãú naìo, ta haîy xem xeït quaï
trçnh Prolog thæûc hiãûn cáu hoíi :
?- member1( b, [ a, b, c ] ).
104 Láûp trçnh lägich trong Prolog
Caïch tçm cuía thuí tuûc member1 trãn âáy tæång tæû member, bàòng caïch
duyãût tæìng pháön tæí, cho âãún khi tçm tháúy âäúi tæåüng cáön tçm, hoàûc danh saïch
âaî caûn.
Thuí tuûc remove tháút baûi nãúu danh saïch khäng chæïa pháön tæí cáön xoaï.
Ngæåìi ta coï thãø sæí duûng remove trong mäüt khêa caûnh khaïc, muûc âêch âãø bäø
sung mäüt pháön tæí måïi vaìo báút cæï âáu trong danh saïch.
Vê duû, nãúu ta muäún âàût pháön tæí a vaìo taûi moüi vë trê báút kyì trong danh
saïch [ 1, 2, 3 ], chè cáön âàût cáu hoíi : Cho biãút danh saïch L nãúu sau khi xoaï a,
ta nháûn âæåüc danh saï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 caïch täøng quaït, pheïp toaïn cheìn insert mäüt pháön tæí X vaìo mäüt danh
saïch List âæåüc âënh nghéa båíi thuí tuûc remove bàòng caïch sæí duûng mäüt danh
saïch låïn hån LargerList laìm tham âäúi thæï hai :
insert( X, List, LargerList ) :-
remove( X, LargerList, List ).
Ta âaî âënh nghéa quan hãû thuäüc vãö trong thuí tuûc member1 bàòng caïch sæí
duûng thuí tuûc append. Tuy nhiãn, ta cuîng coï thãø âënh nghéa laûi quan hãû
thuäüc vãö trong thuí tuûc måïi member2 båíi thuí tuûc remove bàòng caïch xem mäüt
pháön tæí X thuäüc vãö mäüt danh saïch List nãúu X bë xoaï khoíi List :
member2( X, List ) :-
remove( X, List, _ ).
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
L1 X L2 member( X, L )
L [ X | L2 ]
L1 S L3 sublist( S, L )
L2
III.2. Hoaïn vë
Âäi khi, ta cáön taûo ra caïc hoaïn vë cuía mäüt danh saïch. Ta xáy dæûng quan
hãû permutation coï hai tham biãún laì hai danh saïch, maì mäüt danh saïch laì hoaïn
vë cuía danh saïch kia. Ta seî táûn duûng pheïp quay lui nhæ sau :
?- permutation( [ a, b, c ], P ).
P = [ a, b, c ];
P = [ a, c, b ];
P = [ b, a, c ];
...
Nguyãn lyï hoaût âäüng cuía thuí tuûc swap dæûa trãn hai træåìng håüp phán
biãût, tuyì theo danh saïch thæï nháút :
1. Nãúu danh saïch thæï nháút räùng, thç danh saïch thæï hai cuîng phaíi räùng.
108 Láûp trçnh lägich trong Prolog
2. Nãúu danh saïch thæï nháút khaïc räùng, thç noï seî coï daûng [ X | L ] vaì âæåüc
tiãún haình hoaïn vë nhæ sau : træåïc tiãn hoaïn vë L âãø nháûn âæåüc L1, sau
âoï cheìn X vaìo táút caí caïc vë trê trong L1.
X L
hoaïn vë L
Cheìn X taûi mäüt vë trê âãø nháûn âæåüc mäüt hoaïn vë cuía [ X | L ]
Hçnh III.4. Mäüt caïch xáy dæûng hoaïn vë permutation cuía danh saïch [ X | L ].
Ta nháûn âæåüc hai mãûnh âãö tæång æïng våïi thuí tuûc nhæ sau :
permutation( [ ], [ ] ).
permutation( [ X | L ], P ) :-
permutation( L, L1 ), insert( X, L1, P ).
Mäüt phæång phaïp khaïc laì loaûi boí pháön tæí X khoíi danh saïch âáöu tiãn,
hoaïn vë pháön coìn laûi cuía danh saïch naìy âãø nháûn âæåüc danh saïch P, sau âoï
thãm X vaìo pháön âáöu cuía P. Ta coï chæång trçnh khaïc permutation2 nhæ sau :
permutation2( [ ], [ ] ).
permutation2( L, [ X | P ] ) :-
remove( X, L, L1 ), permutation2( L1, P ).
Tæì âáy, ta coï thãø khai thaïc thuí tuûc hoaïn vë, chàóng haûn (chuï yï khi chaûy
Arity Prolog cáön goî vaìo 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
Hoàûc nãúu sæí duûng permutation theo caïch khaïc nhæ sau :
?- permutation( L, [ a, b, c ] ).
Prolog seî raìng buäüc liãn tiãúp cho L âãø âæa ra 6 hoaïn vë khaïc nhau coï thãø.
Tuy nhiãn, nãúu NSD yãu cáöu mäüt giaíi phaïp khaïc, Prolog seî 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.
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
caïc säú tæû nhiãn âæåüc taûo sinh liãn tiãúp nhåì kyî thuáû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 buäüc thæûc hiãûn
quay lui. Khi âoï, luáût thæï hai âæåüc váûn duûng âãø taûo sinh säú tæû nhiãn tiãúp
theo vaì cæï thãú tiãúp tuûc cho âãún khi NSD quyãút âënh dæìng chæång trçnh (^C).
sao cho Object phaíi laì pháön tæí cuäúi cuìng cuía danh saïch List. Haîy viãút
thaình hai mãûnh âãö, trong âoï coï mäüt mãûnh âãö sæí duûng append, mãûnh âãö
kia khäng sæí duûng append.
4. Âënh nghéa hai vë tæì :
Cáúu truïc danh saïch 113
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 pheïp láúy ra pháön tæí thæï N
trong mäüt danh saïch. Tháút baûi nãúu danh saïch khäng coï âuí N pháön tæí.
Chæång trçnh hoaû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 vaì pháön tæí nhoí nháút trong
mäüt danh saïch caïc säú. Chæång trçnh hoaû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 chuyãøn mäüt danh saïch phæïc håüp, laì danh saïch
maì mäùi pháön tæí coï thãø laì mäüt danh saïch con chæïa caïc danh saïch con
phæïc håüp khaïc, thaình mäüt danh saïch phàóng laì danh saïch chè chæïa caïc
pháön tæí trong táút caí caïc danh saïch con coï thãø, giæî nguyãn thæï tæû luïc
âáöu. Chæång trçnh hoaû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 caïc chæång trçnh Prolog thæûc hiãûn caïc vë tæì xæí lyï táûp håüp cho åí pháön
lyï thuyãút (muûc II).
Cáúu truïc danh saïch 115
12. Sæí duûng vë tæì forall âãø viãút chæång trçnh Prolog kiãøm tra hai danh saïch
coï råìi nhau (disjoint) khäng ? Chæång trçnh hoaû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, vaì Action. Vê duû dæåïi âáy kiãøm
tra viãûc thæûc hiãûn caïc pheïp toaïn säú hoüc trong danh saïch L laì âuïng âàõn.
?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]), Result =:=
Formula).
Result = _G615
Formula = _G616
Yes
14. Sæí duûng vë tæì forall âãø viãút chæång trçnh Prolog kiãøm tra mäüt danh saïch
coï laì mäüt táûp håüp con cuía mäüt danh saïch khaïc hay khäng ? Chæång trçnh
hoaû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æí duûng vë tæì append gheïp hai danh saïch âãø viãút caïc chæång trçnh
Prolog thæûc hiãûn caïc viãûc sau :
prefixe(L1, L2) danh saïch L1 âæïng træåïc (prefixe list) danh saïch L2.
suffixe(L1, L2) danh saïch L1 âæïng sau (suffixe list) danh saïch L2.
isin(L1, L2) caïc pháön tæí cuía danh saïch L1 coï màût trong danh saïch
L2.
16. Sæí duûng phæång phaïp Quicksort viãút chæång trçnh Prolog sàõp xãúp nhanh
mäüt danh saïch caïc säú âaî cho theo thæï tæû tàng dáön.
17. Âoüc hiãøu chæång trçnh sau âáy räöi dæûng laûi thuáût toaïn :
/* Missionarys & Cannibals */
/* Traïnh voìng làûp */
lNotExist(_,[]).
lNotExist(X,[T|Q]) :-
X\==T, lNotExist(X,Q).
116 Láûp trçnh lägich trong 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 ngàn 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
Y
-
-
4 -
-
2 -
-
+ + + + + + + + +
3 6 X
Hçnh I.1.Haìm báûc thang coï hai báûc.
Khi chaûy chæång trçnh, giaí sæí ràòng biãún X cuía haìm f( X, Y ) âaî âæåüc nháûn
mäüt giaï trë säú âãø coï thãø thæûc hiãûn pheïp so saïnh trong thán haìm. Tæì âáy, xaíy
ra hai khaí nàng sæí duûng kyî thuáût nhaït càõt nhæ sau :
f( 1, Y), 2 < Y.
2<0
Tháút baûi
Hçnh I.2. Taûi vë trê «Nhaït càõt», caïc luáût 2 vaì 3 âaî biãút træåïc tháút baû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.
Thæí luáût 1 7 < 3 tháút baûi, quay lui, thæí luáût 2 (nhaït càõt chæa âæåüc sæí
duûng).
Thæí luáût 2 3 ≤ 7 thoaí maîn, nhæng 7 < 6 tháút baûi, quay lui, thæí luáût 3
(nhaït càõt chæa âæåüc sæí duûng).
Thæí luáût 3 6 <= 7 thoaí maîn.
Âãún âáy, ta laûi tháúy xuáút hiãûn chæång trçnh thæûc hiãûn keïm hiãûu quaí. Khi
xaíy ra âêch X < 3 (nghéa laì 7 < 3) tháút baûi, âêch tiãúp theo 3 ≤ X (3 ≤ 7) thoaí
maîn, Prolog tiãúp tuûc kiãøm tra âêch trong luáût 3. Nhæng ta biãút ràòng nãúu mäüt
âêch thæï nháút tháút baûi, thç âêch thæï hai bàõt buäüc phaíi âæåüc thoaí maîn vç noï laì
phuí âënh cuía âêch thæï nháút. Viãûc kiãøm tra láön næîa seî tråí nãn dæ thæìa vç âêch
tæång æïng våïi noï coï thãø bë xoaï. Nhæ váûy viãûc kiãøm tra âêch 6 <= X cuía luáût 3
laì khäng cáön thiãút. Våïi nháûn xeït naìy, ta coï thãø viãút laûi chæång trçnh haìm báûc
thang tiãút kiãûm hån nhæ sau :
Nãúu X < 3 thç Y = 0,
Nãúu khäng, nãúu X < 6 thç Y = 2,
Nãúu khäng Y = 4.
Bàòng caïch loaûi khoíi chæång trçnh nhæîng âiãöu kiãûn maì biãút chàõc chàõn seî
âuïng, ta nháûn âæåüc chæång trçnh måïi nhæ sau :
f( X, 0) :- X < 3, !.
f( X, 2) :- X < 6, !.
f( X, 4).
Chæång trçnh naìy cho kãút quaí tæång tæû hai chæång trçnh træåïc âáy
nhæng thæûc hiãûn nhanh hån do âaî loaûi boí hoaìn toaìn nhæîng quay lui khäng
cáön thiãút.
?- f(1, Y ).
Y=0
Yes
?- f(5, Y ).
Y=2
Yes
?- f(7, Y ).
Y=4
Yes
Nhæng váún âãö gç seî xaíy ra nãúu báy giåì ta laûi loaûi boí hãút caïc nhaït càõt ra
khoíi chæång trçnh ? Chàóng haûn :
Kyî thuáût láûp trçnh Prolog 121
f( X, 0) :- X < 3.
f( X, 2) :- X < 6.
f( X, 4).
Våïi låìi goüi :
?- f( 1, Y ).
Y = 0;
Y = 2;
Y = 4;
No
Prolog âæa ra nhiãöu cáu traí låìi nhæng khäng âuïng. Nhæ váûy, viãûc sæí
duûng nhaït càõt âaî laìm thay âäøi âäöng thåìi nghéa thuí tuûc vaì nghéa khai baïo.
Kyî thuáût nhaït càõt coï thãø âæåüc mä taí nhæ sau :
Ta goüi «âêch cha» laì âêch tæång æïng våïi pháön âáöu cuía mãûnh âãö chæïa nhaït
càõt. Ngay khi gàûp nhaït càõt, Prolog xem ràòng mäüt âêch âaî âæåüc thoaí maîn mäüt
caïch tæû âäüng, vaì gêåïi haûn sæû læûa choün caïc mãûnh âãö trong phaûm vi giæîa låìi goüi
âêch cha vaì thåìi âiãøm thæûc hiãûn nhaït càõt. Táút caí caïc mãûnh âãö tæång æïng våïi
caïc âêch con chæa âæåüc kiãøm tra so khåïp giæîa âêch cha vaì nhaït càõt âãöu âæåüc boí
qua.
Âãø minh hoaû, ta xeït mãûnh âãö coï daûng :
H :- G1, G2, ... Gm, ! , ... , Bn.
Giaí sæí ràòng mãûnh âãö naìy âæåüc khåíi âäüng båíi mäüt âêch G håüp nháút âæåüc
våïi H, khi âoï, G laì âêch cha. Cho âãún khi gàûp nhaït càõt, Prolog âaî tçm âæåüc
caïc låìi giaíi cho caïc âêch con G1, G2, ... Gm.
Ngay sau khi thæûc hiãûn nhaït càõt, caïc âêch con G1, G2, ... Gm bë «vä hiãûu
hoaï», kãø caí caïc mãûnh âãö tæång æïng våïi caïc âêch con naìy cuîng bë boí qua. Hån
næîa, do G håüp nháút våïi H nãn Prolog khäng tiãúp tuûc tçm kiãúm âãø so khåïp H
våïi âáöu (head) cuía caïc mãûnh âãö khaïc.
Chàóng haûn, aïp duûng nguyãn lyï trãn cho vê duû sau :
C :- P, Q, R, ! S, T, U.
C :- V.
A :- B, C, D.
?- A.
Giaí sæí A, B, C, D, P, ... âãöu laì caïc haûng. Taïc âäüng cuía nhaït càõt khi thæûc
hiãûn âêch C nhæ sau : quaï trçnh quay lui xaíy ra bãn trong danh saïch caïc âêch
122 Láûp trçnh lägich trong Prolog
P, Q, R, nhæng ngay khi thæûc hiãûn nhaït càõt, moüi con âæåìng dáùn âãún caïc
mãûnh âãö trong danh saïch P, Q, R âãöu bë boí qua. Mãûnh âãö C thæï hai :
C :- V.
cuîng bë boí qua. Tuy nhiãn, viãûc quay lui váùn coï thãø xaíy ra bãn trong danh
saïch caïc âêch S, T, U. Âêch cha cuía mãûnh âãö chæïa nhaït càõt laì C åí trong mãûnh
âãö :
A :- B, C, D.
Nhæ váûy, nhaït càõt chè taïc âäüng âäúi våïi mãûnh âãö C, maì khäng taïc âäüng âäúi
våïi A. Viãûc quay lui tæû âäüng trong danh saïch caïc âêch B, C, D váùn âæåüc thæûc
hiãûn, âäüc láûp våïi nhaït càõt hiãûn diãûn trong C.
2. Kiãøm tra mäüt pháön tæí coï thuäüc danh saïch âaî cho khäng
Ta âaî xáy dæûng quan hãû :
membre( X, L).
âãø kiãøm tra pháön tæí X coï nàòm trong danh saïch L hay khäng. Chæång trçnh
nhæ sau :
membre( X, [X | L]).
membre( X, [X | L]) :- membre( X, L).
Tuy nhiãn, chæång trçnh naìy hoaût âäüng mäüt caïch «khäng âån âënh». Nãúu
X xuáút hiãûn nhiãöu láön trong danh saïch, thç báút kyì pháön tæí naìo bàòng X cuîng
âæåüc tçm tháúy. Báy giåì ta chuyãøn membre thaình mäüt quan hãû âån âënh chè
taïc âäüng âäúi våïi pháön tæí X âáöu tiãn. Viãûc thay âäøi ráút âån giaín nhæ sau : chè viãûc
cáúm quay lui ngay khi X âæåüc tçm tháúy, nghéa laì khi mãûnh âãö âáöu tiãn âæåüc
thoaí maîn :
membre( X, [ X | L ]) :- !.
membre( X, [ X | L ]) :- membre( X, L).
Khi âoï, trong vê duû sau, Prolog chè âæa ra mäüt låìi giaíi :
?- membre( X, [a, a, b, c]).
X=a;
No
3. Thãm mäüt pháön tæí vaìo danh saïch maì khäng bë truìng làõp
Thäng thæåìng, khi muäún thãm mäüt pháön tæí måïi, chàóng haûn X, vaìo danh
saïch L, ngæåìi ta muäún træåïc âoï, L khäng chæïa pháön tæí naìy. Giaí sæí quan hãû
cáön xáy dæûng :
ajoute( X, L, L1)
coï X laì pháön tæí måïi cáön thãm vaìo danh saïch L, L1 laì kãút quaí coï chæïa âuïng
mäüt X. Ta láûp luáûn nhæ sau :
ajoute( X, L, [ X | L ] ).
Sau âáy laì caïc váûn duûng chæång trçnh :
?- ajoute( a, [ b, c ], L).
L = [ a, b, c ]
?- ajoute( X, [ b, c ], L).
L = [ b, c ]
X=b
?- ajoute( a, [ b, c, X ], L).
X = _G333
L = [a, b, c, _G333]
?- ajoute( a, [ a, b, c ], L).
L = [a, b, c];
Trong vê duû naìy, nhåì sæí duûng kyî thuáût nhaït càõt, ngæåìi láûp trçnh dãù daìng
thãm mäüt pháön tæí måïi vaìo danh saïch maì khäng laìm truìng làûp pháön tæí âoï.
Nãúu khäng sæí duûng kyî thuáût nhaït càõt, viãûc thãm mäüt pháön tæí måïi vaìo mäüt
danh saïch coï thãø laìm truìng làûp pháön tæí.
Nhæ váûy, kyî thuáût nhaït càõt khäng nhæîng laìm täúi æu hiãûu quaí láûp trçnh,
maì coìn ráút cáön thiãút âãø âàûc taí âuïng âàõn mäúi quan hãû giæîa caïc âäúi tæåüng.
Tæì kãút quaí nhæîng tráûn âáúu âaî coï âæåüc cho trong caïc sæû kiãûn, ta tháúy Ann
vaì Pat âæåüc xãúp haûng quaïn quán (champion), Tom âæåüc xãúp haûng trung bçnh
(combative), coìn Jim thç âæåüc xãúp haûng yãúu keïm (dilettante). Ta coï thãø dãù
daìng xáy dæûng caïc luáût xãúp haûng nhæ sau :
X âæåüc xãúp haûng trung bçnh nãúu
täön taûi Y sao cho X thàõng Y, vaì
täön taûi Z sao cho Z thàõng X.
X âæåüc xãúp haûng quaïn quán nãúu
X thàõng Y, vaì
X khäng bë thua báút kyì âäúi thuí naìo.
Luáût xãúp haûng quaïn quán coï chæïa pheïp phuí âënh (not) maì cho âãún luïc
naìy, ta chæa tçm hiãøu caïch biãøu diãùn nhæ thãú naìo trong Prolog. Luáût xãúp
haûng yãúu keïm cuîng xáy dæûng tæång tæû luáût xãúp haûng quaïn quán. Ta coï thãø
sæí duûng så âäö if-then-else âãø xæí lyï âäöng thåìi hai tçnh huäúng nhæ sau :
Nãúu X thàõng vaì X bë thua khi âáúu våïi báút kyì ai
thç X âæåüc xãúp haûng trung bçnh
nãúu khäng, nãúu X thàõng báút kyì ai
thç X âæåüc xãúp haûng quaïn quán
nãúu khäng, nãúu X luän bë thua
thç X âæåüc xãúp haûng yãúu keïm.
Tæì så âäö trãn ta coï thãø chuyãøn sang Prolog sæí duûng kyî thuáût nhaït càõt âãø
xæí lyï khaí nàng loaûi træì nhau giæîa ba thæï haûng.
classe( X, combative) :-
bat( X, _ ),
bat( _, X ), !.
classe( X, champion) :-
bat( X, _ ), !.
classe( X, dilettante) :-
bat( _, X ).
Chuï yï ràòng khäng nháút thiãút phaíi sæí duûng nhaït càõt trong mãûnh âãö
champion vç baín cháút cuía ba thæï haûng.
126 Láûp trçnh lägich trong Prolog
Ta noïi ràòng X vaì Y khaïc nhau do chuïng khäng thãø khåïp âæåüc våïi nhau :
Nãúu X vaì Y laì âäöng nháút, thç différent( X, Y ) tháút baûi,
Nãúu khäng, différent( X, Y ) thaình cäng.
Ta sæí duûng nhaït càõt vaì âêch fail âãø viãút quan hãû naìy thaình hai luáût :
différent( X, X ) :- !, fail.
différent( X, Y ).
Hoàûc viãút laûi thaình mäüt luáût nhæ sau :
différent( X, Y ) :-
X = Y, !, fail;
true.
Chuï yï ràòng âêch true (âuïng) luän luän thaình cäng.
Tæì âáy, ta coï thãø âënh nghéa vë tæì not(Goal) cho pheïp kiãøm tra âêch khäng
thoaí maîn nhæ sau :
Nãúu Goal thoaí maîn, thç not(Goal) tháút baûi,
Nãúu khäng, not(Goal) thaình cäng.
Chæång trçnh Prolog :
not( P ) :-
P, !, fail;
true.
Háöu hãút caïc phiãn baín Prolog hiãûn nay âãöu coï vë tæì not
not(2 = 3).
Yes
?- not(2 = 2).
No
Sæí duûng vë tæì not, ta coï thãø âënh nghéa laûi caïc quan hãû enjoy, différent vaì
classe nhæ sau :
enjoy( marie, X ) :-
animal( X ),
not (serpent( X )).
différent( X, Y ) :-
not( X = Y ).
classe( X, combatif) :-
bat( X, _ ),
bat( _ , X ).
128 Láûp trçnh lägich trong Prolog
classe( X, champion) :-
bat( X _ ),
not bat( _ , X ).
classe( X, dilettante) :-
bat( _ , X ),
not bat( X, _ ).
I.3.2. Sæí duûng kyî thuáût nhaït càõt vaì phuí âënh
Æu âiãøm cuía kyî thuáût nhaït càõt coï thãø toïm tàõt nhæ sau :
1. Náng cao tênh hiãûu quaí cuía mäüt chæång trçnh nhåì nguyãn tàõc thäng
baïo mäüt caïch tæåìng minh cho Prolog traïnh khäng âi theo nhæîng con
âæåìng dáùn âãún tháút baûi.
2. Kyî thuáût nhaït càõt cho pheïp xáy dæûng nhæîng luáût coï tênh cháút loaûi træì
nhau coï daûng :
p ⇔ (a ∧ b) ∨ (~a ∧ c)
Nãúu ta âaío thæï tæû hai mãûnh âãö :
p :- c.
p :- a, !, b.
thç ta laûi coï cuìng nghéa nhæ ban âáöu :
p ⇔ c ∨ (a ∧ b)
Ngæåìi ta phaíi tháûn troüng khi sæí duûng kyî thuáût nhaït càõt do nhaït càõt laìm
thay âäøi nghéa thuí tuûc vaì laìm tàng nguy cå xaíy ra sai soït trong chæång
trçnh. Nhæ âaî xeït trong caïc vê duû træåïc âáy, viãûc loaûi boí nhaït càõt coï thãø laìm
thay âäøi nghéa khai baïo cuía mäüt chæång trçnh. Tuy nhiãn trong mäüt säú
træåìng håüp, nhaït càõt khäng aính hæåíng âãún nghéa khai baïo. Ngæåìi ta goüi
nhæîng nhaït càõt khäng laìm thay âäøi ngæî nghéa cuía chæång trçnh laì nhaït càõt
xanh (green cuts). Âæïng trãn quan âiãøm láûp trçnh dãù âoüc vaì dãù hiãøu
(readability), caïc nhaït càõt xanh laì an toaìn vaì ngæåìi ta thæåìng hay sæí duûng
chuïng. Tháûm chê, ngæåìi ta coï thãø boí qua sæû coï màût cuía chuïng khi âoüc chæång
trçnh. Ngæåìi ta noïi nhaït càõt xanh laìm roî raìng (explicit) tênh tiãön âënh
(determinism) väún khäng roî raìng (implicit). Thäng thæåìng nhaït càõt xanh
âæåüc âàût ngay sau pheïp kiãøm tra tiãön âënh.
Vê duû sæí duûng nhaït càõt xanh tçm säú min :
minimum(X, Y, X) :-
X =< Y, !.
minimum(X, Y, Y) :-
X > Y, !.
Vê duû sæí duûng nhaït càõt xanh kiãøm tra kiãøu cuía cáy nhë phán caïc säú
nguyãn :
int_bin_tree(ab(X,G,D)) :-
integer(X),
int_bin_tree(G),
int_bin_tree(D).
int_bin_tree(X) :-
integer(X).
Trong caïc træåìng håüp khaïc, caïc nhaït càõt aính hæåíng âãún nghéa khai baïo
âæåüc goüi laì nhaït càõt âoí (red cuts). Sæû coï màût cuía caïc nhaït càõt âoí thæåìng laìm
cho chæång trçnh tråí nãn khoï âoüc, khoï hiãøu. Âãø sæí duûng âæåüc chuïng, NSD
130 Láûp trçnh lägich trong Prolog
phaíi hãút sæïc chuï yï. Vê duû sæí duûng nhaït càõt âoí tçm säú min thay âäøi ngæî
nghéa :
minimum_cut( X, Y, X ) :-
X =< Y, !.
minimum_cut( X, Y, Y ).
Trong mäüt säú træåìng håüp, mäüt cáu hoíi coï thãø khäng liãn quan âãún ngæî
nghéa cuía chæång trçnh. Vê duû vë tæì kiãøm tra mäüt pháön tæí coï thuäüc danh
saïch khäng :
member_cut(X, [ X | _ ] ) :- !.
member_cut(X, [ _ | L ] ) :- member_cut(X, L ).
Våïi cáu hoíi member_cut(X, [ 1, 2, 3 ] ) seî khäng cho kãút quaí X = 2.
?- member_cut(X, [ 1, 2, 3 ] ).
X=1;
No
Thäng thæåìng, âêch fail âæåüc duìng càûp âäi våïi nhaït càõt (cut-fail). Ngæåìi ta
thæåìng âënh nghéa pheïp phuí âënh mäüt âêch (not) bàòng caïch gáy ra sæû tháút
baûi cuía âêch naìy, thæûc cháút laì caïch sæí duûng nhaït càõt coï haûn chãú. Âãø chæång
trçnh dãù hiãùu hån, thay vç sæí duûng càûp âäi cut-fail, ngæåìi ta sæí duûng not. Tuy
nhiãn, pheïp phuí âënh not cuîng khäng phaíi khäng gáy ra nhæîng phiãön phæïc
cho ngæåìi duìng. Nhiãöu khi sæí duûng not khäng hoaìn toaìn chênh xaïc våïi pheïp
phuí âënh trong Toaïn hoüc. Chàóng haûn nãúu trong chæång trçnh coï âënh nghéa
quan hãû man, maì ta âæa ra mäüt cáu hoíi âaûi loaûi nhæ :
?- not( man( marie)).
Khi âoï, Prolog seî traí låìi No nãúu âaî coï âënh nghéa man( marie), traí låìi Yes
nãúu chæa coï âënh nghéa nhæ váûy. Tuy nhiãn, khi traí låìi No, khäng phaíi
Prolog noïi ràòng «Marie khäng phaíi laì mäüt ngæåìi», maì noïi ràòng «Khäng tçm
tháúy trong chæång trçnh thäng tin âãø chæïng minh Marie laì mäüt ngæåìi». Khi
thæûc hiãûn pheïp not, Prolog khäng chæïng minh træûc tiãúp maì tçm caïch chæïng
minh âiãöu ngæåüc laûi. Nãúu chæïng minh âæåüc, Prolog suy ra ràòng âêch not
thaình cäng. Caïch láûp luáûn nhæ váûy âæåüc goüi laì giaí thuyãút vãö thãú giåïi kheïp kên
(hypothesis of the enclosed world). Theo giaí thuyãút naìy, thãú giåïi kheïp kên coï
nghéa laì nhæîng gi täön taûi (âuïng) âãöu nàòm trong chæång trçnh hoàûc âæåüc suy
ra tæì chæång trçnh. Nhæîng gç khäng nàòm trong chæång trçnh, hoàûc khäng
thãø suy ra tæì chæång trçnh, thç seî laì khäng âuïng (sai), hay âiãöu phuí âënh laì
Kyî thuáût láûp trçnh Prolog 131
âuïng. Vç váûy, cáön chuï yï khi sæí duûng phuí âënh do thäng thæåìng, ngæåìi ta âaî
khäng giaí thiãút ràòng thãú giåïi laì kheïp kên. Trong chæång trçnh, do thiãúu khai
baïo mãûnh âãö :
man( marie).
nãn Prolog khäng chæïng minh âæåüc ràòng Marie laì mäüt ngæåìi.
Sau âáy laì mäüt vê duû khaïc sæí duûng pheïp phuí âënh not :
r( a).
q( b).
p( X ) :- not( r( X )).
Nãúu âàût cáu hoíi :
?- q( X ), p( X ).
thç Prolog seî traí låìi :
X=b
Yes
Nhæng nãúu âàût cáu hoíi :
?- p( X ), q( X ).
thç Prolog seî traí låìi :
No
Âãø hiãøu âæåüc vç sao cuìng mäüt chæång trçnh nhæng våïi hai caïch âàût cáu
hoíi khaïc nhau laûi coï hai caïch traí låìi khaïc nhau, ta cáön tçm hiãøu caïch Prolog
láûp luáûn. Trong træåìng håüp thæï nháút, biãún X âæåüc raìng buäüc giaï trë laì b khi
thæûc hiãûn âêch q( X ). Tiãúp tuûc thæûc hiãûn âêch con p( X ), nhåì raìng buäüc X=b,
âêch not( r( X )) thoaí maîn vç âêch r( b ) khäng thoaí maîn, Prolog traí låìi Yes.
Traïi laûi trong træåìng håüp thæï hai, do Prolog thæûc hiãûn âêch con p( X )
træåïc nãn sæû tháút baûi cuía not( r( X )), tæïc r( X ) thaình cäng våïi raìng buäüc X=a,
dáùn âãún cáu traí låìi No.
Mä phoíng mäüt ätämat hæîu haûn khäng âån âënh vaì maïy Turing.
Láûp kãú hoaûch âi du lëch
Baìi toaïn taïm quán háûu
Âäöng thåìi, ta cuîng trçnh baìy caïch Prolog træìu tæåüng hoaï dæî liãûu.
II.1. Truy cáûp thäng tin cáúu truïc tæì mäüt cå såí dæî liãûu
Sau âáy laì mäüt vê duû cho pheïp biãøu diãùn vaì thao taïc caïc dæî liãûu cáúu truïc.
Tæì âoï, ta cuîng hiãøu caïch sæí duûng Prolog nhæ mäüt ngän ngæî truy váún cå såí dæî
liãûu.
Trong Prolog, mäüt cå såí âæåüc biãøu diãùn dæåïi daûng mäüt táûp håüp caïc sæû
kiãûn. Chàóng haûn, mäüt cå såí dæî liãûu vãö caïc gia âçnh seî mä taí mäùi gia âçnh
(family) nhæ mäüt mãûnh âãö. Mäùi gia âçnh seî gäöm ba pháön tæí láön læåüt : chäöng,
våü (individual) vaì caïc con (children). Do caïc pháön tæí naìy thay âäøi tuy theo
tæìng gia âçnh, nãn caïc con seî âæåüc biãøu diãùn båíi mäüt danh saïch âãø coï thãø
nháûn âæåüc mäüt säú læåüng tuyì yï säú con. Mäùi ngæåìi trong gia âçnh âæåüc biãøu
diãùn båíi bäún thaình pháön : tãn, hoü, ngaìy thaïng nàm sinh vaì viãûc laìm. Thaình
pháön viãûc laìm coï thãø coï giaï trë “tháút nghiãûp” (inactive), hoàûc chè roî tãn cå
quan cäng taïc vaì thu nháûp theo nàm.
Giaí sæí cå såí dæî liãûu chæïa mãûnh âãö âáöu tiãn nhæ sau :
family(
individual( tom, smith, date(7, may, 1960), work(microsoft, 30000) ),
individual( ann, smith, date(9, avril, 1962), inactive),
[ individual( roze, smith, date(16, june, 1991), inactive),
individual( eric, smith, date(23, march, 1993), inactive) ] ).
Dæî liãûu vãö nhæîng gia âçnh khaïc tiãúp tuûc âæåüc bäø sung dæåïi daûng caïc
mãûnh âãö tæång tæû. Hçnh 5.1 dæåïi âáy minh hoaû caïch täø chæïc cå såí dæî liãûu.
Prolog laì mäüt ngän ngæî ráút thêch håüp cho viãûc khäi phuûc thäng tin : ngæåìi
sæí duûng coï thãø goüi caïc âäúi tæåüng maì khäng nháút thiãút chè roî táút caí caïc thaình
pháön. Ngæåìi sæí duûng chè cáön chè ra cáúu truïc cuía caïc âäúi tæåüng maì hoü quan
tám mäüt caïch tæûång træng, khäng cáön phaíi chè ra hãút. Hçnh 1.2 minh hoaû
nhæîng cáúu truïc nhæ váûy. Vê duû, âãø biãøu diãùn nhæîng gia âçnh doìng hoü Smith,
trong Prolog viãút :
family( individual( _ , smith, _ , _ ), _ , _ )
Kyî thuáût láûp trçnh Prolog 133
family
individual individual .
7 may 1960 microsoft 30000 9 avril 1962 roze smith date inactive children []
23 march 1993
Hçnh II.1. Cáúu truïc cáy biãøu diãùn thäng tin vãö mäüt gia âçnh
(a) family (b) family
_ _ .
individual _ _
_ .
_ bob _ _
(c) family _ .
_ []
_ individual .
Firstname Lastname _ _ _ .
_ .
_ _
Hçnh II.2. tênh cháút cáúu truïc cuía caïc âäúi tæåüng Prolog cho pheïp biãøu diãùn :
(a) mäüt gia âçnh Smith naìo âoï ; (b) nhæîng gia âçnh coï âuïng ba con ; (c) nhæîng gia
âçnh coï êt nháút ba con. Riãng træåìng håüp (c) coìn cho pheïp biãøu diãùn tãn cuía ngæåìi våü
nhåì sæû raìng buäüc caïc biãún Firstname vaì Lastname.
Nhæîng dáúu gaûch dæåïi doìng nhæ âaî biãút laì caïc biãún nàûc danh, ngæåìi sæí
duûng khäng cáön quan tám âãún giaï trë cuía chuïng. Mäüt caïch tæång tæû, nhæîng
gia âçnh coï ba con âæåüc biãøu diãùn båíi :
family( _ , _ , [ _ , _ , _ ] )
134 Láûp trçnh lägich trong Prolog
Ta cuîng coï thãø âàût cáu hoíi tçm nhæîng ngæåìi våü trong nhæîng gia âçnh coï êt
nháút ba con :
?- family( _ , individual( Firstname, Lastname, _ , _ ), [ _ , _ , _ | _ ] ).
Nhæîng vê duû trãn âáy chè ra ràòng ta coï thãø biãøu diãùn caïc âäúi tæåüng båíi cáúu
truïc cuía chuïng maì khäng cáön quan tám âãún näüi dung, bàòng caïch boí qua
nhæîng tham âäúi vä âënh.
Sau âáy laì mäüt säú mãûnh âãö âæåüc âæa thãm vaìo cå såí dæî liãûu caïc gia âçnh
âãø coï thãø âàût caïc cáu hoíi váún tin khaïc nhau (coï thãø bäø sung thãm caïc gia âçnh
måïi båíi mãûnh âãö family) :
husban( X ) :- % X laì mäüt ngæåìi chäöng
family( X , _ , _ ).
wife( X ) :- % X laì mäüt ngæåìi våü
family( _, X , _ ).
chidren( X ) :- % X laì mäüt ngæåìi con, chuï yï caïc tãn biãún chæî hoa
family( _, _ , Chidren ),
ismember( X, Chidren ).
ismember( X, [ X | L ] ). % coï thãø sæí duûng mãûnh âãö member cuía Prolog
ismember( X, [ Y | L ] ) :-
ismember( X, L ).
exist( Individual ) :- % moüi thaình viãn cuía gia âçnh
husban( Individual ) ;
wife( Individual ) ;
chidren( Individual ).
dateofbirth( individual( _ , _, Date , _ ), Date ).
salary( individual( _ , _, _ , work( _ , S ) ), S ). % thu nháûp cuía ngæåìi lao
âäüng
salary( individual( _ , _, _ , inactive ), 0 ). % ngæåìi khäng coï nguäön thu
nháûp
Báy giåì ta coï thãø âàût caïc cáu hoíi nhæ sau :
1. Tçm tãn hoü cuía nhæîng ngæåìi coï màût trong cå såí dæî liãûu :
?- exist( individual( Firstname, Lastname, _ , _ ) ).
2. Tçm nhæîng ngæåìi con sinh nàm 1991 :
?- chidren( X ), dateofbirth( X, date( _ , _ , 1991 ) ).
3. Tçm nhæîng ngæåìi våü coï viãûc laìm :
Kyî thuáût láûp trçnh Prolog 135
Caïc phiãn baín Prolog âãöu coï thãø tênh âäü daìi (length) cuía mäüt danh saïch
(xem muûc III chæång 1 træåïc âáy, ta cuîng âaî tçm caïch xáy dæûng quan hãû
naìy). Báy giåì ta coï thãø aïp duûng âãø tçm nhæîng gia âçnh coï nguäön thu nháûp
nhoí hån 5000 tênh theo âáöu ngæåìi :
?- family( Husban, Wife, Chidren ),
total( [ Husban, Wife | Chidren ], Income )
length( [ Husban, Wife | Chidren ], N ),
Income / N < 5000. % N laì säú ngæåìi trong mäüt gia âçnh
136 Láûp trçnh lägich trong Prolog
Viãûc sæí duûng caïc bäü choün laìm thay âäøi dãù daìng mäüt chæång trçnh Prolog.
Giaí sæí ta muäún thay âäøi dæî liãûu cuía mäüt chæång trçnh, ta chè cáön âënh nghéa
laûi caïc bäü choün, pháön coìn laûi cuía chæång trçnh váùn hoaût âäüng nhæ cuî.
138 Láûp trçnh lägich trong Prolog
khäng hãö âoüc mäüt kyï tæû naìo. Nghéa laì pháön cáu vaìo váùn khäng thay âäøi,
nhæng ätämat âaî thay âäøi traûng thaïi.
a
a
s1 s2
b ε b
ε
s4 a s3
Hçnh II.3. Mäüt oâtämat hæîu haûn khäng âån âënh bäún traûng thaïi.
Ngæåìi ta noïi ätämat thæìa nháûn cáu vaìo nãúu täön taûi mäüt daîy caïc chuyãøn
tiãúp trong âäö thë sao cho :
1. Luïc âáöu, ätämat åí traûng thaïi âáöu (vê duû s1).
2. Ätämat kãút thuïc viãûc âoaïn nháûn cáu vaìo vaì åí traûng thaïi thæìa nháûn
(s3).
3. Caïc nhaîn trãn caïc cung cuía con âæåìng chuyãøn tiãúp tæì traûng thaïi âáöu
âãún traûng thaïi thæìa nháûn tæång æïng våïi cáu vaìo laì xáu âaî âoüc.
Trong quaï trçnh âoaïn nháûn cáu vaìo, ätämat quyãút âënh læûa choün mäüt
trong säú caïc chuyãøn tiãúp coï thãø âãø tiãúp tuûc. Âàûc biãût, ätämat coï thãø thæûc hiãûn
hay khäng thæûc hiãûn mäüt ε−chuyãøn tiãúp, nãúu traûng thaïi hiãûn haình cho pheïp.
Ätämat khäng thæìa nháûn cáu vaìo nãúu noï khäng råi vaìo traûng thaïi thæìa
nháûn duì âaî âoüc hãút cáu vaìo, hoàûc khäng coìn khaí nàng tiãúp tuûc chuyãøn tiãúp
maì cáu vaìo chæa kãút thuïc, hoàûc coï thãø bë quáøn vä haûn.
Nhæ âaî biãút, caïc ätämat hæîu haûn khäng âån âënh træìu tæåüng coï mäüt tênh
cháút thuï vëû : taûi mäùi thåìi âiãøm, ätämat coï khaí nàng læûa choün, trong säú caïc
chuyãøn tiãúp coï thãø, mäüt chuyãøn tiãúp “täút nháút” âãø thæìa nháûn cáu vaìo.
Chàóng haûn, ätämat cho åí Hçnh II.3 seî thæìa nháûn caïc xáu ab vaì aabaab,
nhæng khäng thæìa nháûn caïc xáu abb vaì abba. Mäüt caïct täøng quaït, ätämat
thæìa nháûn moüi xáu kãút thuïc båíi ab, nhæng khäng thæìa nháûn caïc xáu khaïc.
Trong Prolog, mäüt ätämat âæåüc âënh nghéa båíi ba quan hãû :
140 Láûp trçnh lägich trong Prolog
1. Mäüt quan hãû mäüt ngäi satisfaction cho pheïp xaïc âënh caïc traûng thaïi
thæìa nháûn cuía ätämat.
2. Mäüt quan hãû ba ngäi trans cho pheïp xaïc âënh caïc traûng thaïi chuyãøn
tiãúp, chàóng haûn :
trans( S1, X, S2 ).
coï nghéa laì ätämat chuyãøn tiãúp tæì traûng thaïi S1 qua traûng thaïi S2 sau
khi âoüc kyï tæû X.
3. Mäüt quan hãû hai ngäi epsilon chè ra pheïp chuyãøn tiãúp räùng tæì traûng
thaïi S1 qua traûng thaïi S2 :
epsilon( S1, S2 ).
Ätämat âaî cho åí Hçnh II.3 âæåüc mä taí båíi caïc mãûnh âãö Prolog nhæ sau :
satisfaction( s3 ).
trans( s1, a, s1 ).
trans( s1, a, s2 ).
trans( s1, b, s1 ).
trans( s2, b, s3 ).
trans( s3, b, s4 ).
epsilon( s2, s4 ).
epsilon( s3, s1 ).
Âãø biãøu diãùn caïc xáu kyï tæû trong Prolog, ta seî sæí duûng kiãøu danh saïch.
Chàóng haûn xáu aab âæåüc biãøu diãùn båíi [ a, b, a ]. Xuáút phaït tæì mäüt cáu vaìo,
ätämat væìa mä taí trãn âáy seî mä phoíng quaï trçnh âoaïn nháûn, bàòng caïch âoüc
láön læåüt caïc pháön tæí cuía danh saïch, âãø thæìa nháûn hay khäng thæìa nháûn.
Theo âënh nghéa, ätämat hæîu haûn khäng âån âënh seî thæìa nháûn cáu vaìo
nãúu, xuáút phaït tæì traûng thaïi âáöu, sau khi âoüc hãút cáu (xæí lyï hãút moüi pháön tæí
cuía danh saïch), ätämat råi vaìo traûng thaïi thæìa nháûn. Quan hãû hai ngäi
accept sau âáy cho pheïp mä phoíng quaï trçnh âoaïn nháûn mäüt cáu vaìo tæì mäüt
traûng thaïi âaî cho :
accept( State, InputString )
Quan hãû accept laì âuïng nãúu State laì traûng thaïi âáöu vaì InputString laì mäüt
cáu vaìo.
Kyî thuáût láûp trçnh Prolog 141
kyï tæû âáöu tiãn pháön coìn laûi cuía cáu vaìo
X
S S1
(a)
cáu vaìo
ε
S S1
(b)
Ba mãûnh âãö cho pheïp âënh nghéa quan hãû naìy, tæång æïng våïi ba træåìng
håüp nhæ sau :
1. Xáu räùng [ ] âæåüc thæìa nháûn taûi traûng thaïi S nãúu ätämat âang åí taûi traûng
thaïi S vaì S laì mäüt traûng thaïi thæìa nháûn.
2. Mäüt xáu khaïc räùng âæåüc thæìa nháûn taûi traûng thaïi S nãúu âáöu âoüc âang
åí taûi vë trê âoüc kyï tæû âáöu tiãn cuía xáu âãø sau khi âoüc, ätämat chuyãøn
qua traûng thaïi S1 vaì xuáút phaït tæì traûng thaïi S1 naìy, ätämat thæìa
nháûn toaìn bäü pháön coìn laûi cuía cáu vaìo (xem minh hoaû åí Hçnh II.4 (a) ).
3. Mäüt xáu khaïc räùng âæåüc thæìa nháûn taûi traûng thaïi S nãúu ätämat coï thãø
thæûc hiãûn mäüt ε-chuyãøn tiãúp tæì traûng thaïi S qua traûng thaïi S1 vaì xuáút
phaït tæì traûng thaïi S1 naìy, ätämat thæìa nháûn toaìn bäü pháön coìn laûi cuía
cáu vaìo (xem minh hoaû åí Hçnh II.4 (b) ).
Báy giåì, ta coï thãø yãu cáöu ätämat nháûn biãút xáu aaab båíi cáu hoíi sau :
?- accept( s1, [ a, a, a, b ] ).
Yes
seî gáy ra mäüt voìng làûp quáøn vä haûn taûi traûng thaïi s1, trong khi ätämat cäú
gàõng tçm mäüt con âæåìng âãún traûng thaïi thæìa nháûn s3.
b A a, b
a b
0 1 2
Hçnh II.5. Ätämat hæîu haûn âån âënh coï ba traûng thaïi.
Sau âáy laì mäüt säú hoaût âäüng âoaïn nháûn cuía ätämat :
?- parse([b,b,a,a,b,a,b]).
0 [b, b, a, a, b, a, b]
0 [b, a, a, b, a, b]
0 [a, a, b, a, b]
1 [a, b, a, b]
1 [b, a, b]
2 [a, b]
2 [b]
2 []
Yes
?- parse([b,b,a]).
0 [b, b, a]
0 [b, a]
0 [a]
No
• Täi phaíi âi du lëch Milan, Ljubljana vaì Zurich xuáút phaït tæì Paris ngaìy
thæï Ba vaì phaíi quay vãö trong ngaìy thæï Saïu. Laìm sao âãø coï thãø sàõp xãúp
caïc chuyãøn âi cuía täi sao cho mäùi ngaìy khäng âi maïy bay quaï mäüt láön ?
Chæång trçnh Prolog âæåüc dæûa trãn mäüt cå såí dæî liãûu chæïa nhæîng thäng
tin vãö caïc chuyãún bay. Mäùi chuyãún bay laì mäüt quan hãû ba ngäi cho biãút lëch
trçnh bay timetable nhæ sau :
timetable( Place1, Place2, Fly_List).
Danh saïch caïc ngaìy coï chuyãún bay hoàûc laì mäüt danh saïch caïc ngaìy thæï
trong tuáön, hoàûc laì mäüt nguyãn tæí all (cho táút caí caïc ngaìy). Chàóng haûn, sau
âáy laì mäüt quan hãû timetable :
timetable( paris , grenoble ,
[ 9:40 / 10:50 / ba4732 / all ,
11:40 / 12:50 / ba4752 / all ,
18:40 / 19:50 / ba4822 / [ mo , tu , we , th , fr ] ] ).
Lëch trçnh bay âæåüc biãøu diãùn båíi caïc cáúu truïc hai thaình pháön laì giåì vaì
phuït phán caïch nhau båíi pheïp toaïn : (dáúu hai cháúm).
Baìi toaïn chênh âàût ra laì tçm nhæîng läü trçnh chênh xaïc giæîa hai thaình phäú
(nåi âi vaì nåi âãún) vaì mäüt ngaìy naìo âoï âaî cho. Âãø láûp trçnh, ta sæí duûng mäüt
quan hãû coï bäún tham âäúi nhæ sau :
path( Place1 , Place2 , Day, Path )
trong âoï, laì mäüt daîy caïc chuyãún bay thoaí maîn caïc tiãu chuáøn sau :
(1) Nåi âi laì Place1.
(2) Nåi âãún laì Place2.
(3) Táút caí nhæîng chuyãún bay cuìng ngaìy Day trong tuáön.
(4) Táút caí nhæîng chuyãún bay cuía läü trçnh Path thuäüc vãö quan hãû
timetable.
(5) Coï âuí thåïi gian âãø di chuyãøn giæîa caïc chuyãún bay.
Läü trçnh âæåüc biãøu diãùn båíi mäüt danh saïch caïc âäúi tæåüng nhæ sau :
Departure - Arrival : Fly_number : Departure_hour
146 Láûp trçnh lägich trong Prolog
• Âãø mä phoíng quaï trçnh âoaïn nháûn cáu, ätämat tçm âæåüc mäüt läü trçnh
giæîa traûng thaïi âáöu vaì mäüt traûng thaïi thæìa nháûn. Coìn âãø mä phoíng
viãûc láûp kãú hoaûch âi du lëch, chæång trçnh tçm âæåüc mäüt lëch trçnh bay
giæîa thaình phäú xuáút phaït vaì thaình phäú âãún.
Chênh vç váûy, ta coï thãø âënh nghéa mäüt quan hãû vãö läü trçnh path tæång tæû
våïi quan hãû accept, chè coï khaïc laì quan hãû path khäng chæïa chuyãøn tiãúp
räùng.
Xaíy ra hai træåìng håüp nhæ sau :
(1) Nãúu coï mäüt chuyãún bay træûc tiãúp giæîa P1 vaì P2 thç läü trçnh âæåüc ruït
goün thaình :
path( P1 , P2 , Day, [ P1 - P2 : FlyNum : DepH ] ) :-
fly( P1 , P2 , Day , FlyNum , Dep , Arr ).
(2) Nãúu khäng coï mäüt chuyãún bay træûc tiãúp giæîa P1 vaì P2 thç läü trçnh seî
phaíi bao gäöm mäüt chuyãún bay giæîa P1 vaì mäüt thaình phäú trung gian
Kyî thuáût láûp trçnh Prolog 147
P3, räöi mäüt chuyãún bay giæîa P3 vaì P2. Luïc naìy cáön coï âuí thåìi gian âãø
di chuyãøn giæîa hai chuyãún bay, tæì nåi âãún cuía chuyãún bay thæï nháút
âãún nåi xuáút phaït cuía chuyãún bay thæï hai :
path( P1 , P2 , Day , [ P1 - P3 : FlyNum : Dep1 | Path ] ) :-
path( P3 , P2 , Day , Path ),
fly( P1 , P3 , Day , FlyNum1 , Dep1 , Arr1 ),
dephour( Path , Dep2 ) ,
connecting( Arr1 , Dep2 ).
Caïc quan hãû fly, connecting vaì dephour âæåüc xáy dæûng tæång âäúi dãù daìng.
Dæåïi âáy laì chæång trçnh âáöy âuí bao gäöm cå såí dæî liãûu vãö lëch trçnh bay.
Vê duû naìy âån giaín, khäng xaíy ra træåìng håüp coï läü trçnh vä êch, nghéa laì
mäüt läü trçnh khäng dáùn âãún âáu. Ta cuîng tháúy ràòng cå såí dæî liãûu vãö lëch
trçnh bay coìn nhoí. Âãø coï thãø quaín lyï mäüt cå såí dæî liãûu låïn hån, nháút thiãút
phaíi sæí duûng mäüt chæång trçnh láûp kãú hoaûch thäng minh hån.
Sau âáy laì mäüt säú cáu hoíi trãn cå såí dæî liãûu vãö lëch trçnh haìng khäng :
• Nhæîng ngaìy naìo trong tuáön coï mäüt chuyãún bay træûc tiãúp giæîa Paris vaì
Ljubljana ?
?- fly( paris , ljubljana , Day , _ , _ , _ ).
Day = fr;
Day = su;
No
• Laìm caïch naìo âãø coï thãø âi tæì Ljubljana âãún Grenoble ngaìy thæï nàm ?
?- path( ljubljana , grenoble , th, C ).
C = [ ljubljana-paris:yu200:11:10, paris-grenoble:ba4822:18:40 ] ;
C = [ ljubljana-paris:yu212:11:25, paris-grenoble:ba4822:18:40 ] ;
C = [ ljubljana-zurich:ju322:11:30, zurich-paris:sr806:16:10,
paris-grenoble:ba4822:18:40 ]
• Laìm caïch naìo âãø xuáút phaït tæì Paris, coï thãø du lëch Milan, Ljubljana vaì
Zurich trong ngaìy thæï Ba, âãø tråí vãö trong ngaìy thæï Saïu, sao cho mäùi
ngaìy chè thæûc hiãûn khäng quaï mäüt chuyãún bay ?
Âáy laì mäüt cáu hoíi tæång âäúi luíng cuíng. Âãø traí låìi, ta cáön sæí duûng
quan hãû permutation âaî trçnh baìy trong chæång 1, muûc 3. Quan hãû naìy
cho pheïp hoaïn vë táút caí caïc thaình phäú Milan, Ljubljana vaì Zurich sao
cho täön taûi nhæîng chuyãún bay thêch håüp mäùi ngaìy :
?- permutation( [ milan , ljubljana , zurich ] , [ V1, V2, V3 ] ),
fly( paris, V1, tu, FN1, Dep1, Arr1 ),
fly( V1, V2, tu, FN2, Dep2, Arr2 ),
fly( V2, V3, tu, FN3, Dep3, Arr3 ),
fly( V3, paris, fr, FN4, Dep4, Arr4 ).
Kãút quaí -> V1 = ljubljana -> V1 = milan
V2 = zurich V2 = zurich
V3 = milan V3 = ljubljana
FN1 = ju213 FN1 = ba510
Dep1 = 13:20 Dep1 = 8:30
Arr1 = 16:20 Arr1 = 11:20
FN2 = ju322 FN2 = sr621
Dep2 = 11:30 Dep2 = 9:25
Arr2 = 12:40 Arr2 = 10:15
FN3 = sr620 FN3 = yu323
Dep3 = 7:55 Dep3 = 13:30
Arr3 = 8:45 Arr3 = 14:40
FN4 = az458 FN4 = yu200
Dep4 = 9:10 Dep4 = 11:10
Arr4 = 10:0 ; Arr4 = 12:20
150 Láûp trçnh lägich trong Prolog
Hçnh II.6. Mäüt låìi giaíi cuía baìi toaïn taïm quán háûu
Niclaus Wirth trçnh baìy phæång phaïp thæí-sai (trial-and-error) nhæ sau :
− Âàût mäüt quán háûu vaìo cäüt 1 (trãn mäüt haìng tuyì yï);
− Âàût tiãúp mäüt quán háûu thæï hai sao cho 2 quán khäng àn nhau;
− Tiãúp tuûc âàût quán thæï 3, v.v...
Låìi giaíi coï daûng mäüt voìng làûp theo giaí ngæî Pascal nhæ sau :
Xeït-cäüt-âáöu ;
repeat
Thæí_cäüt ;
if An_toaìn then begin
Âàût_quán_háûu_vaìo ;
Xeït_cäüt_kãú_tiãúp;
end else Quay_laûi ;
until Âaî_xong_våïi_cäüt_cuäúi or Âaî_quay_laûi_quaï_cäüt_âáöu ;
Kyî thuáût láûp trçnh Prolog 151
II.5.1. Sæí duûng danh saïch toaû âäü theo haìng vaì cäüt
Ta cáön tçm caïch biãøu diãùn caïc vë trê trãn baìn cåì. Giaíi phaïp træûc tiãúp nháút
laì sæí duûng mäüt danh saïch taïm pháön tæí maì mäùi pháön tæí tæång æïng våïi ä âàût
quán háûu. Mäùi pháön tæí laì mäüt càûp säú nguyãn giæîa 1 vaì 8 chè toaû âäü cuía quán
háûu :
X/Y
8 •
7 •
6 •
5 •
4 •
3 •
2 •
1 •
1 2 3 4 5 6 7 8
Hçnh II.7. Mäüt låìi giaíi cuía baìi toaïn taïm quán háûu,
biãøu diãùn båíi danh saïch [ 1/4, 2/2, 3/7, 4/3, 5/6, 6/8, 7/5, 8/1 ] .
ÅÍ âáy, pheïp toaïn / khäng phaíi laì pheïp chia, maì chè laì caïch täø håüp hai toaû
âäü cuía mäüt ä baìn cåì. Hçnh 5.6 trãn âáy laì mäüt låìi giaíi khaïc cuía baìi toaïn taïm
quán háûu âæåüc biãøu diãùn dæåïi daûng mäüt danh saïch nhæ sau :
[ 1/4, 2/2, 3/7, 4/3, 5/6, 6/8, 7/5, 8/1 ]
Tæì caïch biãøu diãùn danh saïch, ta cáön tçm låìi giaíi coï daûng :
[ X1/Y1, X2/Y2, X3/Y3, ... , X8/Y8 ]
152 Láûp trçnh lägich trong Prolog
Ta cáön tçm caïc giaï trë cuía caïc biãún X1, Y1, X2, Y2, X3, Y3, ... , X8, Y8. Do
caïc quán háûu phaíi nàòm trãn caïc cäüt khaïc nhau âãø khäng thãø àn láùn nhau,
nãn ta coï ngay giaï trë cuía caïc toaû âäü X, vaì låìi giaíi luïc naìy coï daûng :
[ 1/Y1, 2/Y2, 3/Y3, ... , 8/Y8 ]
Cho âãún luïc naìy, baìi toaïn taïm quán háûu chè âàût ra âäúi våïi baìn cåì 8 × 8.
Tuy nhiãn, låìi giaíi phaíi dæû kiãún âæåüc cho træåìng håüp täøng quaït khi láûp trçnh.
ÅÍ âáy, ta seî tháúy ràòng chênh træåìng håüp täøng quaït laûi âån giaín hån baìi toaïn
ban âáöu. Baìn cåì 8 × 8 chè laì mäüt træåìng håüp riãng.
Âãø giaíi quyãút cho træåìng håüp täøng quaït, ta chuyãøn kêch thæåïc 8 quán háûu
thaình mäüt säú quán háûu báút kyì naìo âoï (mäùi cäüt mäüt quán háûu), kãø caí säú cäüt
bàòng khäng. Ta xáy dæûng quan hãû solution tæì hai tçnh huäúng sau :
1. Danh saïch caïc quán háûu laì räùng : danh saïch räùng cuîng laì mäüt låìi giaíi
vç khäng xaíy ra sæû táún cäng naìo.
solution( [ ] ).
2. Danh saïch caïc quán háûu khaïc räùng vaì coï daûng nhæ sau :
[ X/Y | Others ]
Trong træåìng håüp thæï hai, quán háûu thæï nháút nàòm trãn ä X/Y, coìn nhæîng
quán háûu khaïc nàòm trong danh saïch Others. Nãúu danh saïch naìy laì mäüt låìi
giaíi, thç nhæîng âiãöu kiãûn sau âáy phaíi âæåüc thoaí maîn :
1. Nhæîng quán háûu trong danh saïch Others khäng thãø táún cäng láùn
nhau, âiãöu naìy noïi lãn ràòng Others cuîng laì mäüt låìi giaíi.
2. Vë trê X vaì Y cuía nhæîng quán háûu phaíi nàòm giæîa 1 vaì 8.
3. Mäüt quán háûu taûi vë trê X/Y khäng thãø táún cäng mäüt quán háûu naìo
khaïc trong danh saïch Others.
Âäúi våïi âiãöu kiãûn thæï nháút, quan hãû solution phaíi âæåüc goüi mäüt caïch âãû
quy.
Âiãöu kiãûn thæï hai noïi lãn ràòng Y phaíi thuäüc vãö danh saïch [ 1, 2, 3, 4, 5, 6,
7, 8 ]. ÅÍ âáy, ta khäng cáön quan tám âãún vë trê X, vç noï phaíi tæång håüp våïi
danh saïch kãút quaí traí vãö nhæ ta âaî xaïc âënh ngay tæì âáöu. Nghéa laì X phaíi
thuäüc vãö nhæîng giaï trë âaî âæåüc áún âënh tæång æïng.
Kyî thuáût láûp trçnh Prolog 153
Giaí sæí âiãöu kiãûn thæï ba âæåüc giaíi 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 ).
• Caïc quán háûu khäng thãø nàòm trãn cuìng âæåìng cheïo chênh hoàûc phuû.
nghéa laì khoaíng caïch giæîa caïc ä trãn truûc X phaíi khaïc våïi caïc ä trãn
truûc Y.
noattack( X/Y, [ X1/Y2 | Others ] ) :-
Y =\= Y1,
Y1 - Y =\= X1 - X,
Y1 - Y =\= X - X1,
noattack( X/Y, Others ).
Dæåïi âáy laì chæång trçnh Prolog âáöy âuí thæï nháút coï chæïa danh saïch låìi
giaíi laì quan hãû model. Mä hçnh laìm cho viãûc tçm låìi giaíi cho baìi toaïn taïm
quán háûu tråí nãn âån giaín hån.
% chæång trçnh thæï nháút giaíi baìi toaïn taïm quán háûu
% The problem of the eight queens - Program 1
% −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
154 Láûp trçnh lägich trong Prolog
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æí duûng vë tæì not, ta viãút laûi chæång trçnh nhæ sau :
solution( [ ] ).
solution( [ X/Y | Others ] ) :-
solution( Others ),
member( Y, [ 1, 2, 3, 4, 5, 6, 7, 8 ] ),
not( attack( X/Y, Others )).
member( A, [ A | L ] ).
member( A, [ B | L ] ) :-
member( A, L).
% Mä hçnh låìi giaíi
Kyî thuáût láûp trçnh Prolog 155
do mäùi cäüt chè âàût âuïng mäüt quán háûu. Thæûc ra, ta khäng máút thäng tin nãúu
boí âi caïc toaû âäü X. Ta coï thãø biãøu diãùn baìn cåì chè våïi caïc toaû âäü Y cuía caïc
quán háûu :
[ Y1, Y2, Y3, ... , Y8 ]
Âãø khäng xaíy ra caïc quán háûu nàòm trãn cuìng cäüt, cáön phaíi bäú trê mäùi
quán háûu mäüt haìng. Tæì âáy ta âàût ra raìng buäüc cho caïc toaû âäü Y : mäùi haìng
1, 2, 3, ..., 8 cuía baìn cåì chè âæåüc pheïp âàût duy nháút mäüt quán háûu. Ta nháûn
tháúy ràòng mäùi låìi giaíi laì mäüt hoaïn vë cuía danh saïch caïc säú 1 .. 8 sao cho thæï
tæû cuía mäùi con säú laì khaïc nhau :
[ 1, 2, 3, 5, 6, 7, 8 ]
Mäùi hoaïn vë cuía danh saïch laì mäüt låìi giaíi S sao cho caïc quán háûu åí traûng
thaïi an toaìn (khäng àn âæåüc láùn nhau). Ta coï :
solution( S ) :-
permutation( [ 1, 2, 3, 5, 6, 7, 8 ], S ),
insafety( S ).
Trong chæång 1 træåïc âáy, ta âaî xáy dæûng quan hãû permutation, báy giåì ta
cáön âënh nghéa quan hãû safety. Xaíy ra hai træåìng håüp nhæ sau :
1. Nãúu danh saïch S räùng, khi âoï S cuîng laì låìi giaíi, vç khäng coï quán háûu
naìo táún cäng quán háûu naìo.
insafety( [ ] ).
156 Láûp trçnh lägich trong Prolog
2. Nãúu danh saïch S khaïc räùng, khi âoï S coï daûng [ Queen | Others ]. Ta
tháúy S laì låìi giaíi nãúu caïc quán háûu trong Others laì åí traûng thaïi an
toaìn vaì quán háûu Queen khäng thãø táún cäng quán háûu naìo trong
Others.
(a) (b)
• •
• Others •
• •
Queen
• •
% chæång trçnh thæï hai giaíi baìi toaïn taïm quán háûu
% The problem of the eight queens - Program 2
% −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
solution( Queens ) :-
permutation( [ 1, 2, 3, 4, 5, 6, 7, 8 ], Queens ),
insafety( Queens ).
permutation( [ ], [ ] ).
permutation( [ Head | Tail ], PermList ) :-
permutation( Tail, PermTail ),
remove( Head, PermList, PermTail ).
remove( X, [ X | L ], L ).
remove( X, [ Y | L ], [ Y | L1 ] ) :-
remove( X, L, L1 ).
insafety( [ ] ).
158 Láûp trçnh lägich trong Prolog
Sau khi yãu cáöu, Prolog âæa ra caïc låìi giaíi nhæ sau :
?- solution( S ).
S = [5, 2, 6, 1, 7, 4, 8, 3] ;
S = [6, 3, 5, 7, 1, 4, 2, 8] ;
S = [6, 4, 7, 1, 3, 5, 2, 8] ;
S = [3, 6, 2, 7, 5, 1, 8, 4] ;
S = [6, 3, 1, 7, 5, 8, 2, 4] ;
S = [6, 2, 7, 1, 3, 5, 8, 4] ;
S = [6, 4, 7, 1, 8, 2, 5, 3] ;
…
Yes
II.5.3. Sæí duûng toaû âäü theo haìng, cäüt vaì caïc âæåìng cheïo
Trong chæång trçnh thæï ba, ta âæa ra láûp luáûn nhæ sau :
Cáön phaíi âàût mäùi quán háûu lãn mäüt ä, nghéa laì trãn mäüt haìng, mäüt cäüt,
mäüt âæåìng cheïo nghëch (tæì dæåïi lãn) vaì mäüt âæåìng cheïo thuáûn (tæì trãn
xuäúng). Âãø moüi quán háûu khäng thãø àn âæåüc láùn nhau, chuïng phaíi âæåüc âàût
mäùi quán trãn mäüt haìng, mäüt cäüt, mäüt âæåìng cheïo nghëch vaì mäüt âæåìng cheïo
thuáûn phán biãût. Nhæ váûy, ta dæû kiãún mäüt hãû thäúng toaû âäü biãøu diãùn caïc
quán háûu nhæ sau :
x cäüt
y haìng
u âæåìng cheïo nghëch
v âæåìng cheïo thuáûn
Caïc toaû âäü khäng hoaìn toaìn âäüc láûp våïi nhau : våïi x vaì y âaî cho, ta coï thãø
tênh âæåüc u vaì v :
u=x-y
v=x+y
Kyî thuáût láûp trçnh Prolog 159
Sau âáy laì bäún miãön giaï trë tæång æïng våïi bäún toaû âäü X, Y, U, V :
Dx = [ 1, 2, 3, 4, 5, 6, 7, 8 ]
Dy = [ 1, 2, 3, 4, 5, 6, 7, 8 ]
Du = [ -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7 ]
Dy = [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ]
Baìi toaïn taïm quán háûu báy giåì âæåüc phaït biãøu laûi nhæ sau : haîy choün ra
taïm bäü bäún (X, Y, U, V), sao cho X ∈ Dx, Y ∈ Dy, U ∈ Du, V ∈ Dv vaì khäng
bao giåì sæí duûng hai láön cuìng mäüt pháön tæí trong mäùi miãön giaï trë Dx, Dy, Du
vaì Dv.
Nhæ váûy, U vaì V âæåüc sinh ra tæì viãûc læûa choün X vaì Y.
-7 -2 u=x–y +7
| | | | | | | | | | | | | | |
8
7
6
5
4 •
3
2
1
1 2 3 4 5 6 7 8 x
2 6 u=x+y 16
| | | | | | | | | | | | | | |
Hçnh II.9. Quan hãû giæîa cäüt, haìng, âæåìng cheïo nghëch vaì âæåìng cheïo thuáûn
Ä coï âaïnh dáúu () trong hçnh coï toaû âäü x = 2, y = 4, u = 2 – 4 = -2, v = 2 + 4 = 6.
Låìi giaíi âaûi khaïi coï daûng nhæ sau : cho træåïc bäún miãön giaï trë, haîy choün
mäüt vë trê cho quán háûu âáöu tiãn, räöi xoaï caïc toaû âäü cuía chuïng trong miãön
giaï trë, sau âoï sæí duûng caïc miãön giaï trë måïi naìy âãø âàût caïc quán háûu khaïc
tiãúp theo. Caïc vë trê trãn baìn cåì cuîng âæåüc biãøu diãùn båíi mäüt danh saïch caïc
160 Láûp trçnh lägich trong Prolog
toaû âäü trãn truûc Y. Chæång trçnh Prolog giaíi baìi toaïn taïm quán háûu seî sæí
duûng quan hãû :
sol ( ListY, Dx, Dy, Du, Dv )
cho pheïp raìng buäüc caïc toaû âäü cuía caïc quán háûu (trong ListY), xuáút phaït tæì
nguyãn lyï laì caïc quán háûu nàòm trãn caïc cäüt liãn tiãúp nhau láúy tæì Dx. Caïc toaû
âäü Y, U vaì V âæåüc láúy tæì Dy, Du vaì Dv tæång æïng.
Låìi giaíi cuäúi cuìng cuía baìi toaïn taïm quán háûu laì mãûnh âãö :
?- solution( S )
cho pheïp goüi sol våïi danh saïch caïc tham âäúi âáöy âuí. Chæång trçnh nhæ sau :
Thuí tuûc sol væìa xáy dæûng trãn âáy coï tênh täøng quaït vç coï thãø duìng âãø
giaíi quyãút baìi toaïn cho N quán háûu báút kyì (trãn baìn cåì N × N). Sæû khaïc nhau
laì åí chäù miãön giaï trë Dx, Dy, … thay âäøi tuyì theo N.
Âãø taûo sinh caïc miãön giaï trë naìy mäüt caïch tæû âäüng, ta âënh nghéa thuí tuûc :
gen( N1, N2, List ).
âãø taûo ra mäüt danh saïch caïc säú nguyãn giæîa N1 vaì N2 :
List = [ N1, N1 + 1, N1 + 2, …, N2 – 1, N2 ]
Thán thuí tuûc nhæ sau :
gen( N, N, [ N ] ).
gen( N1, N2, [ N1 | List ] ) :-
N1 < N2,
M is N1 + 1,
gen( M, N2, List ).
Báy giåì ta thay âäøi quan hãû solution nhæ sau :
solution( N, S ) :-
gen( 1, N, Dxy),
Nu1 is 1 – N,
Nu2 is N - 1,
gen( Nu1, Nu2, Du ),
Nv2 is N + N,
gen( 2, Nv2, Dv ),
sol( S, Dxy, Dxy, Du, Dv).
Giaí sæí cáön giaíi baìi toaïn våïi 12 quán háûu, ta coï låìi goüi nhæ sau :
?- solution( 12, S ).
S = [ 1, 3, 5, 8, 10, 12, 6, 11, 2, 7, 9, 4]
…
Yes
dæî liãûu nhàòm tiãút kiãûm bäü nhåï coï báút låüi åí chäù laì thæåìng xuyãn phaíi tênh âi
tênh laûi mäüt säú giaï trë dæî liãûu træåïc khi coï thãø sæí duûng chuïng.
Trong ba låìi giaíi trãn âáy, låìi giaíi thæï ba minh hoaû roî neït hån caí vãö caïch
xáy dæûng caïc cáúu truïc dæî liãûu xuáút phaït tæì mäüt táûp håüp caïc pháön tæí âaî cho
coï nhiãöu raìng buäüc. Hai chæång trçnh âáöu xáy dæûng táút caí caïc hoaïn vë coï thãø
räöi láön læåüt kiãøm tra coï phaíi hoaïn vë âang xeït laì mäüt låìi giaíi khäng âãø loaûi boí
nhæîng hoaïn vë khäng täút træåïc khi xáy dæûng chuïng mäüt caïch âáöy âuí. Viãûc
xaïc âënh caïc hoaïn vë gáy ra täún thåìi gian do phaíi thæûc hiãûn nhiãöu láön caïc
pheïp tênh säú hoüc. Chæång trçnh thæï ba traïnh âæåüc âiãöu naìy nhåì caïch biãøu
diãùn baìn cåì håüp lyï.
Vaìo tæì Ra
baìn phêm maìn hçnh,
maïy in
Doìng Doìng
Tãûp 1 Trçnh Tãûp 3
dæî liãûu dæî liãûu
Tãûp 2 Prolog Tãûp 4
vaìo ra
... ...
Hçnh III.1. Liãn laûc giæîa mäüt trçnh Prolog vaì nhiãöu tãûp .
Trçnh Prolog coï thãø âoüc dæî liãûu vaìo tæì nhiãöu tãûp, âæåüc goüi laì doìng dæî liãûu
vaìo (input streams), sau khi tênh toaïn, coï thãø ghi lãn nhiãöu tãûp, âæåüc goüi laì
164 Láûp trçnh lägich trong Prolog
doìng dæî liãûu ra (output streams). Dæî liãûu âãún tæì giao diãûn NSD (baìn phêm),
räöi kãút quaí gæíi ra maìn hçnh, cuîng âæåüc xæí lyï nhæ laì nhæîng doìng dæî liãûu vaìo
ra khaïc. Âáy laì nhæîng tãûp giaí (pseudo-file) âæåüc âàût tãn laì user (ngæåìi sæí
duûng). Caïc tãûp chæïa chæång trçnh, hay dæî liãûu Prolog âæåüc NSD læûa choün âàût
tãn tæû do (miãùn laì khaïc user) trong khuän khäø cuía hãû âiãöu haình.
Khi thæûc hiãûn mäüt trçnh Prolog, taûi mäùi thåìi âiãøm, chè coï hai tãûp hoaût
âäüng laì tãûp âang âæåüc âoüc, âæåüc goüi laì doìng vaìo hiãûn haình (active input
streams), vaì tãûp âang âæåüc ghi, âæåüc goüi laì doìng ra hiãûn haình (active output
streams).
Luïc måïi chaûy chæång trçnh, doìng vaìo hiãûn haình laì baìn phêm vaì doìng ra
hiãûn haình laì maìn hçnh (hoàûc maïy in) tæång æïng våïi chãú âäü vaìo ra chuáøn
user.
Âoüc tæì doìng vaìo hiãûn haình mäüt giaï trë âãø khåïp våïi haûng
Term. Nãúu Term laì biãún thç âæåüc láúy giaï trë naìy vaì vë tæì thoaí
maîn. Nãúu khäng thãø säú khåïp, vë tæì traí vãö tháút baûi maì khäng
read(Term) tiãún haình quay lui. Mäùi haûng trong tãûp phaíi kãút thuïc båíi
mäüt dáúu cháúm vaì mäüt dáúu caïch (space) hoàûc dáúu Enter. Khi
thæûc hiãûn read maì âang åí vë trê cuäúi tãûp, Term seî nháûn giaï
trë end_of_file.
Ghi lãn tãûp hiãûn haình giaï trë cuía haûng Term. Nãúu Term laì
write(Term) biãún thç giaï trë naìy âæåüc âæa ra theo kiãøu cuía Prolog. Caïc
kiãøu giaï trë khaïc nhau âãöu coï thãø âæa ra båíi write.
Vê duû III.1 :
NSD âënh hæåïng doìng vaìo laì tãûp myexp1.pl :
?- see(‘myexp1.pl'). % Bàõt âáöu âoüc tãûp myexp1.pl.
Yes
Hoàûc :
?- see('C:/My Documents/Gt-Prolog/Example/myexp1.pl').
Yes
Âêch see(F) luän luän âæåüc thoaí maîn, træì træåìng håüp xaíy ra sai soït âäúi
våïi caïc tãûp dæî liãûu. Chuï yï tãn thæ muûc vaì âæåìng dáùn âæåüc viãút theo kiãøu
Unix vaì âæåüc âàût trong càûp dáúu nhaïy âån. Sau khi laìm viãûc trãn tãûp
myexp1.pl, lãûnh seen cho pheïp tråí vãö chãú âäü chuáøn.
?- seen.
Yes
Vê duû III.2 :
Duìng read âãø âoüc dæî liãûu vaìo báút kyì tæì baìn phêm :
?- read(N).
| 100.
N = 100
Yes
?- read('Your name ?').
| asimo.
No
?- read('Your name ?').
166 Láûp trçnh lägich trong Prolog
Vê duû III.4 :
Duìng write âãø âæa dæî liãûu báút kyì ra maìn hçnh :
?- write(asimo).
asimo
Yes
Caïch ghi lãn tãûp cuîng theo cå chãú tæång tæû, dæî liãûu âæåüc ghi liãn tiãúp bàõt
âáöu tæì vë trê cuäúi cuìng cuía âäúi tæåüng. Prolog khäng thãø quay lui hay ghi âeì
lãn pháön âaî ghi træåïc âoï.
Prolog chè laìm viãûc våïi caïc tãûp daûng vàn baín (text files), nghéa laì chè vaìo
ra våïi caïc chæî caïi chæî säú vaì kyï tæû âiãöu khiãøn ASCII.
âæa ra maìn hçnh 5 dáúu caïch räöi âãún mäüt dáúu * vaì qua doìng.
Vê duû III.6 :
Viãút thuí tuûc tênh luyî thæìa 3 cuía mäüt säú :
cube( N, C) :-
C is N * N* N.
Giaí sæí ta muäún tênh nhiãöu láön cube, khi âoï ta phaíi viãút nhiãöu láön âêch :
?- cube( 2, X ).
X=8
Yes
?- cube( 5, Y ).
V 125
?- cube( 12, Z).
Z = 1728
Yes
Âãø chè cáön sæí duûng mäüt âêch maì coï thãø tênh nhiãöu láön cube, ta cáön sæía laûi
chæång trçnh nhæ sau :
cube :-
read( X ),
compute( X ).
compute( stop ) :- !.
compute( N) :-
C is N *N* N,
write( C),
cube.
Nghéa thuí tuûc cuía chæång trçnh cube nhæ sau : âãø tçm luyî thæìa 3, træåïc
tiãn âoüc X, sau âoï thæûc hiãûn tênh toaïn våïi X vaì in ra kãút quaí. Nãúu X coï giaï trë
laì stop, ngæìng ngay, nãúu khäng, thæûc hiãûn tênh toaïn mäüt caïch âãû quy. Chuï yï
khi nháûp dæî liãûu cho vë tæì read, cáön kãút thuïc båíi mäüt dáúu cháúm :
?- cube.
|: 3.
27
|: 10.
1000
|: 18.
5832
|: stop.
Yes
Kyî thuáût láûp trçnh Prolog 169
Ta coï thãø tiãúp tuûc thay âäøi chæång trçnh. Mäüt caïch træûc giaïc, nãúu viãút laûi
cube maì khäng sæí duûng compute nhæ sau laì sai :
cube :-
read( stop), !.
cube :-
read( N),
C is N *N * N,
write( C),
cube.
båíi vç, giaí sæí NSD goî vaìo 3, âêch read( stop) tháút baûi, nhaït càõt boí qua dæî liãûu
naìy vaì do váûy, cube(3) khäng âæåüc tênh. Lãûnh read( N) tiãúp theo seî yãu cáöu
NSD vaìo tiãúp dæî liãûu cho N. Nãúu N laì säú, viãûc tênh toaïn thaình cäng, ngæåüc
laûi, nãúu N laì stop, Prolog seî thæûc hiãûn tênh toaïn trãn caïc dæî liãûu phi säú stop :
?- cube1.
|: 3. % Prolog boí qua, khäng tênh
|: 9.
729 % Prolog tênh ra kãút quaí cho N = 9
|: 4. % Prolog boí qua, khäng tênh
|: stop. % Prolog baïo läùi
ERROR: Arithmetic: `stop/0' is not a function
^ Exception: (9) _L143 is stop*stop*stop ? creep
Thäng thæåìng caïc chæång trçnh khi thæûc hiãûn cáön sæû tæång taïc giæîa NSD
vaì hãû thäúng. NSD cáön âæåüc biãút kiãøu vaì giaï trë dæî liãûu chæång trçnh yãu cáöu
nháûp vaìo. Muäún váûy, chæång trçnh cáön âæa ra doìng yãu cáöu hay låìi nhàõc
(prompt). Haìm cube âæåüc viãút laûi nhæ sau :
cube :-
write('Please enter a number: '),
read( X ),
compute( X ).
compute( stop ) :- !.
compute( N) :-
C is N *N* N,
write('The cube of '), write(N),
write(' is '), write( C), nl,
cube.
cube.
Please enter a number: 3.
The cube of 3 is 27
Please enter a number: stop.
170 Láûp trçnh lägich trong Prolog
Yes
Vê duû III.7
Ta xáy dæûng thuí tuûc displaylist sau âáy âãø in ra caïc pháön tæí cuía danh
saïch :
displaylist( [ ]).
displaylist( [X | L ] ) :-
write( X ), nl,
displaylist( L).
?- displaylist( [[a, b, c], [d, e, f], [g, h, i]]).
[a, b, c]
[d, e, f]
[g, h, i]
Yes
Ta tháúy trong træåìng håüp caïc pháön tæí cuía mäüt danh saïch laûi laì nhæîng
danh saïch nhæ trãn thç täút hån caí laì in chuïng ra trãn cuìng haìng :
displaylist( [ ]).
displaylist( [X | L ] ) :-
write( X ), tab( 1),
displaylist( L), nl.
displaylist( [[a, b, c], [d, e, f], [g, h, i]]).
[a, b, c] [d, e, f] [g, h, i]
Yes
Thuí tuûc dæåïi âáy in ra caïc pháön tæí kiãøu danh saïch phàóng trãn cuìng
haìng :
displaylist2( [ ] ).
displaylist2( [ L | L1 ] ) :-
inline( u),
displaylist2( L1 ), nl.
inline( [ ] ).
inline( [ X I L ] ) :-
write( X ), tab( 1),
inline( L).
?- displaylist2( [[a, b, c], [d, e, f], [g, h, i]]).
abcdefghi
Yes
Vê duû dæåïi âáy in ra danh saïch caïc säú nguyãn dæåïi daûng mäüt âäö thë gäöm
caïc doìng keí laì caïc dáúu sao (hoa thë) * :
Kyî thuáût láûp trçnh Prolog 171
barres( [ N | L]) :-
asterisk(N), nl,
barres(L).
asterisk( N) :-
N > 0,
write( *),
N1 is N - 1,
asterisk( N1).
asterisk( N) :-
N =< 0.
?- barres([3, 4, 6, 5, 9]).
***
****
******
*****
*********
No
Vê duû III.8 :
Âoüc näüi dung mäüt tãûp vaìo danh saïch caïc säú nguyãn :
readmyfile( File, List) :-
see( File),
readlist( List),
seen,
!.
readlist( [X | L ]) :-
get0(X),
X =\= -1,
!,
read_list( L).
readlist( [ ] ).
Yes
Prolog cho pheïp viãút goün trong mäüt danh saïch nhæ sau :
?- [‘myexp.pl' ].
Âãø naûp vaì biãn dëch âäöng thåìi nhiãöu tãûp chæång trçnh khaïc nhau, coï thãø
liãût kã trong mäüt danh saïch nhæ sau :
?- ['file1.pl', 'file2.pl'].
Sau khi caïc chæång trçnh âaî âæåüc naûp vaìo bäü nhåï, NSD bàõt âáöu thæûc hiãûn
chæång trçnh. NSD coï thãø xem näüi dung toaìn bäü chæång trçnh nhåì vë tæì :
?- listing.
hoàûc xem mäüt mãûnh âãö naìo âoï :
?- listing(displaylist).
displaylist( [ ]).
displaylist( [X | L ] ) :-
write( X ),
tab( 1),
displaylist( L), nl.
Yes
III.3. ÆÏng duûng chãú âäü laìm viãûc våïi caïc tãûp
III.3.1. Âënh daûng caïc haûng
Giaí sæí mäüt baín ghi cå såí dæî liãûu, laì mäüt sæû kiãûn coï daûng cáúu truïc haìm tæí
cuía Prolog, coï näüi dung nhæ sau :
family( individual(tom, smith, date(7, may, 1960), work(microsoft, 30000)),
individual( ann, smith, date(9, avril, 1962), inactive),
[ individual( roza, smith, date(16, june, 1991), inactive),
individual( eric, smith, date(23, march, 1993), inactive) ] ).
Ta cáön in ra näüi dung baín ghi sæí duûng vë tæì write(F) theo quy caïch nhæ
sau :
parents
tom smith, birth day may 7,1960, work microsoft, salary 30000
ann smith, birth day avril 9, 1962, out of work
children
roza smith, birth day june 16, 1991, out of work
eric smith, birth day march 23, 1993, out of work
Ta xáy dæûng thuí tuûc writefamily( F) nhæ sau :
Kyî thuáût láûp trçnh Prolog 173
Thuí tuûc fileprocess âoüc vaì xæí lyï láön læåüt tæìng haûng cuía F cho âãún khi âoüc
hãút tãûp. Mä hçnh thuí tuûc nhæ sau :
filetreat :-
read( Term),
treat( Term).
treat( end_of_file) :- !. % Kãút thuïc tãûp
treat( Term) :-
treatment( Term), % Xæí lyï haûng hiãûn haình
filetreat. % Xæí lyï pháön coìn laûi cuía tãûp
Trong thuí tuûc trãn, treatment( Terme) thãø hiãûn moüi thao taïc coï thãø taïc
âäüng lãn haûng. Chàóng haûn thuí tuûc dæåïi âáy liãût kã tæìng haûng cuía tãûp kãø tæì
doìng thæï N tråí âi cho âãún hãút tãûp, keìm theo thæï tæû coï màût cuía haûng âoï trong
tãûp :
viewfile( N) :-
read( Term),
viewterm( Term, N).
viewterm( end_of_file, _ ) :- !.
viewterm( Term, N) :-
write( N), tab( 2),
write( Term), nl,
N1 is N + 1,
viewfile( N1).
?- see('exp.txt'), viewfile(1), see( user), seen.
1 parent(pam, bob)
2 parent(tom, bob)
3 parent(tom, liz)
4 parent(bob, ann)
5 parent(bob, pat)
…
Yes
Sau âáy laì mäüt mä hçnh khaïc âãø xæí lyï tãûp. Giaí sæí file1 laì tãûp dæî liãûu
nguäön chæïa caïc haûng coï daûng :
object( NoObject, Description, Price, FurnisherName).
Mäùi haûng mä taí mäüt pháön tæí cuía danh saïch caïc âäúi tæåüng. Giaí sæí ràòng
tãûp cáön xáy dæûng file2 chæïa caïc âäúi tæåüng do cuìng mäüt nhaì cung cáúp cáúp
haìng. Trong tãûp naìy, tãn nhaì cung cáúp âæåüc viãút mäüt láön åí âáöu tãûp, maì
Kyî thuáût láûp trçnh Prolog 175
khäng xuáút hiãûn trong caïc âäúi tæåüng, coï daûng object( No, Desc, Price). Thuí
tuûc taûo tãûp nhæ sau :
createfile(Furnisher) :-
write(Furnisher), write( ‘.‘), nl,
creatremaining(Furnisher).
creatremaining( Fournisseur) :-
read( Objet),
treat( Objet, Furnisher).
treat( end_of_file) :- !.
treat(object( No, Desc, Price, Furn), Furn) :-
write( object( No, Desc, Price) ),
write( ‘.‘), nl,
creatremaining(Furn).
treat( _ , Furnisher) :-
creatremaining(Furnisher).
Giaí sæí file1 laì tãûp
see(' file1.txt'),tell(' file2.txt'), createfile(suzuki), seen, see(user), told,
tell(user).
Vê duû III.10 :
Sao cheïp näüi dung mäüt tãûp lãn mäüt tãûp khaïc :
copie :-
repeat,
read(X),
mywrite(X),
X == end_of_file, !.
mywrite( end_of_file).
mywrite( X) :-
write( X), write( '.'), nl.
Âêch sau cho pheïp cäpy tæì tãûp nguäön f1.txt vaìo tãûp âêch f2.txt :
?- tell('f2.txt'), see('f1.txt'), copie, seen, told.
Yes
Trong thuí tuûc copie coï sæí duûng vë tæì repeat. Vë tæì repeat luän luän thaình
cäng, taûo ra mäüt voìng làûp vä haûn. Vë tæì repeat âæåüc âënh nghéa nhæ sau :
repeat.
repeat :- repeat.
tçnh huäúng kyï tæû âoüc vaìo hoàûc laì mäüt khoaíng träúng, hoàûc laì mäüt chæî caïi,
hoàûc laì mäüt dáúu cháúm kãút thuïc. Sau âáy laì thuí tuûc del_space :
del_space :-
get0( C),
put( C),
follow( C).
follow( 46) :- !. % 46 laì maî ASCII cuía dáúu cháúm
follow( 32) :- !, % 32 laì maî ASCII cuía dáúu khoaíng träúng
get( C), % Boí qua caïc dáúu khoaíng träúng tiãúp theo
put( C),
follow( C).
follow( Letter) :-
del_space.
Chaûy thæí nhæ sau :
?- del_space.
|: The robot try to cast the balls to the basket.
The robot try to cast the balls to the basket.
Yes
Vê duû III.13 :
Xáy dæûng thuí tuûc quaín lyï caïc cuäüc goüi dëch vuû xe taxi chåí haình khaïch
nhåì caïc nguyãn tæí sau :
Tãn caïc cuäüc goüi call1, call2, ...
Tãn caïc laïi xe chauffeur1, chauffeur2, ...
Tãn caïc xe taxi taxi1, taxi2, ...
Vë tæì taxi( X ) kiãøm tra mäüt nguyãn tæí coï biãøu diãùn âuïng mäüt taxi theo
caïch biãøu diãùn nhæ trãn khäng :
taxi( T ) :-
name( T, Tlist),
name( taxi, L),
append( L, _ , Tlist).
Mäüt caïch tæång tæû, ta coï thãø xáy dæûng caïc vë tæì chauffer vaì taxi.
Vê duû III.14 :
Sau âáy ta xáy dæûng thuí tuûc cho pheïp taûo ra mäüt nguyãn tæí bàòng caïch täø
håüp caïc kyï tæû. Thuí tuûc readsentence( Wordlist) seî âoüc mäüt cáu thuäüc ngän
ngæî tæû nhiãn räöi gaïn cho Wordlist danh saïch caïc giaï trë maî biãøu diãùn trong
cuía caïc kyï tæû trong cáu. Tiãúp theo, mäùi cáu âæåüc xem laì mäüt danh saïch caïc
tæì, mäùi tæì âæåüc chuyãøn thaình mäüt nguyãn tæí.
readsentence( WordList) :-
get0( Char),
readchain( Char, WordList).
readchain( 46,[ ] ) :- !. % dáúu cháúm kãút thuïc cáu
readchain( 32, WordList) :-
readsentence(WordList). % Boí qua caïc dáúu khoaíng träúng
readchain( L, [ W | WordList ] ) :-
readletter( L, Letters, Nextchar ), % Âoüc caïc kyï tæû cuía tæì tiãúp theo
name( W, Letters),
readchain( Nextchar, WordList).
readletter( 46, [ ], 46) :- !. % kãút thuïc tæì laì mäüt dáúu cháúm
readletter( 32, [ ], 32) :- !. % kãút thuïc tæì laì mäüt dáúu khoaíng
träúng
readletter( C, [ C | Letters] , Nextchar) :-
get0( Char),
readletter( Char, Letters, Nextchar).
Kyî thuáût láûp trçnh Prolog 179
assert((P :- B, C, D)).
coï thãø laìm thay âäøi näüi dung mäüt mãûnh âãö trong chæång trçnh. Tuy nhiãn,
ngæåìi ta khuyãn khäng nãn sæí duûng lãûnh naìy.
retract(P)
Loaûi boí P khoíi cå såí dæî liãûu. Vê duû cho cå såí dæî liãûu luïc ban âáöu :
personal(tom).
personal(ann).
personal(bob).
Sau khi thæûc hiãûn âêch :
?- retract(personal(ann)).
cå såí dæî liãûu luïc naìy chè coìn :
personal(tom).
personal(bob).
Coï thãø sæí duûng biãún trong retract nhæ sau :
Kyî thuáût láûp trçnh Prolog 181
?- retract(personal(X)).
X = tom ;
X = bob ;
No
Luïc naìy cå såí dæî liãûu âaî räùng.
abolish(Term, Arity)
Loaûi boí táút caí caïc haûng Term coï cáúp Arity khoíi cå såí dæî liãûu. Vê duû :
?- abolish(personal, 2).
Loaûi boí táút caí caïc haûng Term coï cáúp Arity=2.
Vê duû III.15
Xáy dæûng bäü siãu diãùn dëch Prolog trong Prolog, viãûc xoaï mäüt âêch âæåüc
viãút laûi nhæ sau :
prove(Goal) :- call(Goal).
hoàûc :
prove(Goal) :- Goal.
hoàûc viãút caïc mãûnh âãö :
prove(true).
prove((Goal1, Goal2)) :-
prove(Goal1),
prove(Goal2).
prove(Goal) :-
clause(Goal, Body),
prove(Body).
182 Láûp trçnh lägich trong Prolog
baìi toaïn taïm quán háûu. Caïch biãøu diãùn dæî liãûu sæí duûng nhiãöu thäng
tin tiãút kiãûm âæåüc tênh toaïn, màûc duì laìm cho chæång trçnh tråí nãn
ræåìm raì, khoï cä âoüng.
• Kyî thuáût täøng quaït hoaï mäüt baìi toaïn, tuy træìu tæåüng, nhæng laûi laìm
tàng khaí nàng hæåïng âãún låìi giaíi, laìm âån giaín hoaï phaït biãøu baìi toaïn.
Laìm viãûc våïi tãûp
Cuìng våïi chãú âäü tæång taïc cáu hoíi-traí låìi, quaï trçnh vaìo ra vaì chãú âäü laìm
viãûc våïi tãûp âaî laìm phong phuï mäi træåìng laìm viãûc cuía Prolog.
• Caïc tãûp trong Prolog âãöu hoaût âäüng theo kiãøu tuáön tæû. Prolog phán biãût
doìng vaìo hiãûn haình vaì doìng ra hiãûn haình.
• Thiãút bë cuäúi (terminal) cuía NSD gäöm maìn hçnh vaì baìn phêm âæåüc xem
nhæ mäüt tãûp giaí coï tãn laì user.
• Prolog coï nhiãöu vë tæì coï sàôn âãø xæí lyï caïc doìng vaìo-ra.
• Khi laìm viãûc våïi tãûp, chãú âäü âoüc ghi laì xæí lyï tæìng kyï tæû hoàûc tæìng haûng.
184 Láûp trçnh lägich trong Prolog
6. Chàóng haûn :
difference( [ a, b, c, d ], [ b, d, e, f ], [ a, c ] )
7. Haîy âënh nghéa vë tæì unifiable( List1, Term, List2) âãø kiãøm tra so khåïp,
trong âoï List2 laì danh saïch táút caí caïc pháön tæí cuía List1 coï thãø so khåïp våïi
Term nhæng khäng thæûc hiãûn pheïp thãú trãn caïc biãún âaî âæåüc so khåïp. Vê
duû :
?- unifiable( [ X, bibo, t( Y ) ], t(a), List ).
List = [X, t( Y )]
Chuï yï ràòng X vaì Y váùn laì caïc biãún tæû do khäng thæûc hiãûn pheïp thãú t(a) cho
X, hay pheïp thãú a cho Y. Muäún váûy, thæûc hiãûn hæåïng dáùn sau :
Sæí duûng pheïp phuí âënh not( Term1 = Term2). Nãúu quan hãû Term1 =
Term2 âæåüc thoaí maîn, khi âoï, not( Term1 = Term2) seî tháút baûi, vaì pheïp
thãú biãún khäng xaíy ra.
8. Baìi toaïn maî âi tuáön. Giaí sæí caïc ä cuía baìn cåì vua 8×8 âæåüc biãøu diãùn båíi
caïc càûp toaû âäü coï daûng X/Y, våïi X vaì Y nàòm trong khoaíng 1 vaì 8.
(a) Âënh nghéa quan hãû jump( case1, case2 ), bàòng caïch sæí duûng luáût âi
cuía quán maî, vaì giaí sæí ràòng case1 luän luän bë raìng buäüc. Vê duû :
?- jump( 1/1, C ).
C = 3/2;
C = 2/3;
No
(b) Âënh nghéa quan hãû mvt_ knight( path ), våïi path laì mäüt danh saïch gäöm
caïc ä biãøu diãùn läü trçnh caïc bæåïc nhaíy håüp lyï cuía quán maî trãn baìn cåì
räùng.
(c) Sæí duûng quan hãû mvt_ knight, viãút mäüt cáu hoíi âãø tçm táút caí caïc läü
trçnh bäún bæåïc nhaíy håüp lyï cuía quán maî, xuáút phaït tæì ä coï toaû âäü 2/1,
âãø âãún biãn bãn phaíi cuía baìn cåì (Y = 8) vaì âãø âãún ä 5/4 sau hai bæåïc
nhaíy.
9. Cho f mäüt tãûp chæïa caïc haûng, haîy âënh nghéa thuí tuûc findterm(Term) âãø
âæa ra maìn hçnh haûng âáöu tiãn cuía f khåïp âæåüc våïi Term ?
10. Cho f mäüt tãûp chæïa caïc haûng, haîy âënh nghéa thuí tuûc findallterm(Term) âãø
âæa ra maìn hçnh táút caí caïc haûng cuía f khåïp âæåüc våïi Term ? Kiãøm tra
tênh cháút biãún Term khäng thãø âæåüc gaïn giaï trë khi thæûc hiãûn tçm kiãúm.
186 Láûp trçnh lägich trong Prolog
11. Haîy måí räüng thuí tuûc del_space âaî âæåüc trçnh baìy trong pháön lyï thuyãút
âãø coï thãø xæí lyï loaûi boí caïc dáúu caïch thæìa nàòm træåïc dáúu pháøy (comma) vaì
chè giæî laûi mäüt dáúu caïch nàòm ngay sau dáúu pháøy.
12. Tæång tæû baìi 3 cho caïc dáúu cháúm cáu khaïc nhæ dáúu cháúm (period), dáúu
cháúm pháøy (semicolon), dáúu cháúm hoíi (question mark), v.v...
13. Âënh nghéa quan hãû firstchar( Atom, Char) cho pheïp kiãøm tra Char coï phaíi
laì kyï tæû âáöu tiãn cuía Atom khäng (Atom bàõt âáöu båíi Char) ?
14. Âënh nghéa thuí tuûc cho pheïp âäøi mäüt danh tæì tiãúng Anh tæì säú êt
(singular) sang säú nhiãöu (plural) âæåüc thæûc hiãûn nhæ sau :
?- plural ( table, X ).
X = tables
Yes
15. AÏp duûng thuí tuûc readsentence âaî âæåüc trçnh baìy trong pháön lyï thuyãút âãø
xáy dæûng thuí tuûc :
?- find( Keyword, Sentence ).
cho pheïp tçm trong tãûp âang âoüc mäüt cáu coï chæïa tæì khoaï Keyword. Cáu
Sentence phaíi åí daûng måïi âæåüc âoüc vaìo chæa xæí lyï, nghéa laì âæåüc biãøu
diãùn båíi mäüt chuäùi kyï tæû, hoàûc båíi mäüt nguyãn tæí.
PHUÛ LUÛC A
is_tree(emptytree).
is_tree(X) :-
X=tree(A, B, C), number(A), is_tree(B), is_tree(C).
187
188 Láûp trçnh lägich trong Prolog
treetest(X) :-
X=(tree(5, tree(2, tree(8, emptytree, emptytree), tree(2, emptytree,
emptytree)), tree(3, emptytree, tree(9, tree(2, emptytree, emptytree),
emptytree)))).
treesort(X) :-
X=(tree(5, tree(3, tree(2, emptytree, emptytree), tree(25, emptytree,
emptytree)), tree(11, tree(8, emptytree, tree(9, emptytree, emptytree)),
tree(13, emptytree, emptytree)))).
affpre(X) :-
X=emptytree.
affpre(X) :-
X=tree(A, B, C), write(A), affpre(B), affpre(C).
affin(X) :-
X=emptytree.
affin(X) :-
X=tree(A, B, C), affin(B), write(A), affin(C).
affpost(X) :-
X=emptytree.
affpost(X) :-
X=tree(A, B, C), affpost(B), affpost(C), write(A).
tree_sort(X) :-
X=emptytree.
tree_sort(X) :-
X=tree(A, B, C), B=emptytree, C=emptytree.
tree_sort(X) :-
X=tree(A, B, C), B=tree(Y, _, _), A>Y, tree_sort(B), C=emptytree.
tree_sort(X) :-
X=tree(A, B, C), B=emptytree, C=tree(Y, _, _), Y>A, tree_sort(C).
tree_sort(X) :-
X=tree(A, B, C), B=tree(Y, _, _), A>Y, tree_sort(B), C=tree(Z, _, _), Z>A,
tree_sort(C).
move(N,A,B,C) :-
M is N-1,
move(M,A,C,B),
inform(A,B),
move(M,C,B,A).
inform(A,B) :-
write([move,disk,from,A,to,B]), nl.
for(X, X, X) :- !.
for(Y, X, Y) :- true.
for(X, Y, Z) :- inc(X, X1), for(X1, Y, Z).
:- public misscann/0.
misscann :- solve(start-state(3,3,left), X), pathwrite(X).
solve(Init-state(0,0,right), Init-state(0,0,right)-finish) :- !.
solve(Init-S1, Final) :-
new_state(S1, S2),
not member(S2, Init),
solve(Init-S1-S2, Final).
new_state(state(M1,C1,left), state(M2,C2,right)) :-
move(M, C),
M =< M1,
C =< C1,
M2 is M1-M,
C2 is C1-C,
balanced(M2, C2).
new_state(state(M1,C1,right), state(M2,C2,left)) :-
190 Láûp trçnh lägich trong Prolog
move(M, C),
M2 is M1+M,
C2 is C1+C,
M2 =< 3,
C2 =< 3,
balanced(M2, C2).
balanced(X, X) :- !.
balanced(3, X) :- !.
balanced(0, X).
move(2,0).
move(1,0).
move(1,1).
move(0,1).
move(0,2).
member(X, Y - X) :- !.
member(X, Y - Z) :- member(X,Y).
pathwrite(A-B) :- !,
pathwrite(A),
nl,
!,
pathwrite(B).
pathwrite(X) :- write(X).
% solve/1
% PROLOG interpreter written in PROLOG (so-called vanilla meta-interpreter)
% usage: ?-solve(PrologGoal).
solve(true).
solve((A, B)) :-
solve(A),
solve(B).
solve(A) :-
clause(A,B),
solve(B).
question(1) :-
write('Con vật này có lông không không ?’),
nl, !, answer(1).
question(2) :-
write(‘Con vâ.t này ăn thịt không ?’),
nl, !, answer(2).
question(3) :-
write(‘Con vâ.t này biết bay không ?’),
nl, !, answer(3).
question(4) :-
write(‘Con vâ.t này có sống trong nước không ?’),
nl, !, answer(4).
question(5) :-
write(‘Con vâ.t này có sống ở Châu Phi không ?’),
nl, !, answer(5).
question(6) :-
write(‘Con vâ.t này có sống ở trong rừng không ?’),
nl, !, answer(6).
question(7) :-
write(‘Con vâ.t này có chân dài không ?’),
nl, !, answer(7).
question(8):-
write(‘Con vâ.t này có ăn cá không ?’),
nl, !, answer(8).
question(9):-
write(‘Con vâ.t này có ăn phù du sinh vật nổi không ?’),
nl, !, answer(9).
question(10):-
write(‘Con vâ.t này có da lông lốm đốm không ?’),
nl, !, answer(10).
question(11):-
write(‘Con vâ.t này có bờm không ?’),
nl, !, answer(11).
question(12):-
write(‘Con vâ.t này có răng nanh hay ngà không ?’),
nl, !, answer(12).
question(13):-
write(‘Con vâ.t này có sừng không ?’),
nl, !, answer(13).
question(14):-
write(‘Con vâ.t này có làm tổ trong núi đá không ?’),
nl, !, answer(14).
question(15):-
write(‘Con vâ.t này có một phần da (lông) màu trắng không ?’),
nl, !, answer(15).
question(16):-
write(‘Con vâ.t này có một phần da (lông) màu nâu không ?’),
nl, !, answer(16).
question(17):-
192 Láûp trçnh lägich trong Prolog
% Hệ chuyên gia đặt câu hỏi hỏi ngược lại người sử dụng
put_questions([]).
put_questions([ X|Y ]) :-
questioner(X),
put_questions(Y).
questioner(X) :-
discovery(X, yes), !.
questioner(X) :-
discovery(X, no), !, fail.
questioner(X) :-
question(X).
explaining(X, Y) :-
write(‘Đây là con :'),
write(X), nl,
write('Bởi vì :'),
nl, explications(Y).
explications([ ]).
explications([ X1|X2 ]) :-
expl(X1), nl,
explications(X2).
expl(1) :-
write(‘Con vâ.t này là loài động vật có vú.').
Phuû luûc A Mäüt säú chæång trçnh Prolog 193
expl(2) :-
write(‘Con vâ.t này là loài động vật ăn thịt.').
expl(3) :-
write(‘Con vâ.t này biết bay.').
expl(4) :-
write('Con vật này sống trong nước.').
expl(5) :-
write(‘Con vâ.t này sống ở Châu Phi.').
expl(6) :-
write(‘Con vâ.t này sống trong rừng.').
expl(7) :-
write(‘Con vâ.t này có chân dài.').
expl(8) :-
write(‘Con vâ.t này ăn cá.').
expl(9) :-
write(‘Con vâ.t này ăn ăn phù du sinh vật nổi.').
expl(10) :-
write(‘Con vâ.t này có da lông lốm đốm.').
expl(11) :-
write(‘Con vâ.t này có bờm.').
PHUÛ LUÛC B
SWI-Prolog laìm viãûc theo chãú âäü tæång taïc (interpreter mode) (xem hçnh).
Dáúu nhàõc lãûnh SWI-Prolog laì mäüt càûp dáúu cháúm hoíi vaì dáúu gaûch ngang (dáúu
træì), âæåüc liãût kã thæï tæû 1, 2, 3... âãø theo doîi quaï trçnh laìm viãûc cuía NSD,
theo sau laì con troí maìn hçnh (dáúu cheìn) nháúp nhaïy :
1 ?-
Âãø ra khoíi SWI-Prolog, duìng lãûnh File/ Exit, hoàûc duìng vë tæì halt :
?- halt.
194
Phuû luûc B Hæåïng dáùn sæí duûng SWI-Prolog 195
ERROR: Undefined procedure <... /...> % NSD âaî goî sai tãn thuí tuûc
hoàûc :
ERROR: Syntax error: Operator expected % NSD âaî goî sai biãøu thæïc, v.v...
II.2. Chaûy trçnh demo
Sau âáy laì vê duû chaûy chæång trçnh demo likes.pl cuía SWI-Prolog. Näüi
dung tãûp likes.pl nhæ sau :
likes(sam, A) :-
indian(A),
mild(A).
likes(sam, A) :-
chinese(A).
likes(sam, A) :-
italian(A).
likes(sam, chips).
italian(pizza).
italian(spaghetti).
chinese(chow_mein).
chinese(chop_suey).
chinese(sweet_and_sour).
mild(dahl).
mild(tandoori).
mild(kurma).
indian(curry).
indian(dahl).
indian(tandoori).
indian(kurma).
NSD naûp chæång trçnh vaìo bäü nhåï båíi lãûnh sau :
?- [swi('demo/likes')].
% swi('demo/likes') compiled 0.00 sec, 2, 340 bytes
Yes
Sau khi tãûp likes.pl âæåüc taíi vaìo bäü nhåï, NSD âàût caïc cáu hoíi vaì nháûn
âæåüc kãút quaí nhæ sau :
?- like(X, Y).
Correct to: likes(X, Y)? Yes
X = sam
Y = dahl ;
X = sam
Y = tandoori ;
Phuû luûc B Hæåïng dáùn sæí duûng SWI-Prolog 197
...
Yes % NSD âaî goî Enter vaì váùn coìn cáu traí låìi.
?-
II.3. Chaûy trçnh demo XPCE
SWI-Prolog âæåüc trang bë chæïc nàng láûp trçnh hæåïng âäúi tæåüng taûo giao
diãûn âäö hoaû, âæåüc goüi laì XPCE, coï maî nguäön tæång thêch våïi Unix/X11 vaì
Wçndows.
NSD coï thãø thæûc hiãûn caïc chæång trçnh demo XPCE bàòng caïch goî :
?- [swi( 'xpce/prolog/demo/pce_demo')].
% contrib(contrib) compiled into pce_contrib 0.02 sec, 1,260 bytes
% swi('xpce/prolog/demo/pce_demo') compiled into pce_demo 0.02 sec,
11,408 bytes
Yes
?- pcedemo.
Yes
Mäüt cæía säø hiãûn ra nhæ sau :
NSD choün xem mäüt troì chåi bàòng caïch læûa tãn troì chåi räöi Open. Sau âoï,
nhàõp chuäüt taûi nuït Quit âãø kãút thuïc chæång trçnh. Vê duû troì chåi Rubiks Cube
nhæ hçnh dæåïi âáy :
198 Láûp trçnh lägich trong Prolog
Settings/Font ... Duìng âãø thay âäøi phäng chæî trong giao diãûn SWI-Prolog.
Settings/User init file ...
Soaûn thaío tãûp cáúu hçnh pl.ini chæïa caïc thäng tin caìi âàût hãû thäúng vaì chuï
thêch.
Settings/Stack sizes ...
Cho pheïp âënh nghéa laûi kêch thæåïc khäng gian laìm viãûc cuía caïc danh
saïch âáøy xuäúng (stack sizes).
Hçnh II.3 Âënh nghéa kêch thæåïc danh saïch âáøy xuäúng
Run/Interrupt
Ngàõt mäüt tiãún trçnh Prolog (Prolog process) coï thãø sæí duûng täø håüp phêm
Control-C coï cuìng hiãûu quaí tæång tæû. Luïc naìy, xuáút hiãûn âäúi thoaûi :
Action (h for help) ? Options:
a: abort b: break
c: continue e: exit
200 Láûp trçnh lägich trong Prolog
g: goals t: trace
h (?): help
Action (h for help) ? abort
ERROR: Execution Aborted
% Execution Aborted
?-
Run/New thread
Taûo mäüt cæía säø laìm viãûc måïi âãø thæûc hiãûn chæång trçnh. Trong cæía säø måïi
naìy coï thãø duìng chung chæång trçnh vaì dæî liãûu âaî coï màût trong cæía säø laìm
viãûc chênh.
Debug/Edit spy points ...
Soaûn thaío caïc âiãøm ngàõt trong caïc vë tæì.
Help Tçm âoüc caïc näüi dung hæåïng dáùn sæí duûng SWI-Prolog khaïc nhau.
âãø liãût kã caïc doìng lãûnh trong cæía säø laìm viãûc chênh cuía Prolog.
Hçnh II.4. Cæía säø soaûn thaío vàn baín PceEmacs cuía SWI-Prolog.
SWI-Prolog coï sàôn mäüt hãû soaûn thaío PceEmacs ráút thuáûn tiãûn âãø soaûn
thaío vaì thæûc hiãûn chæång trçnh. Goî vaìo doìng lãûnh :
?- emacs.
âãø måí cæía säø soaûn thaío vàn baín nhiãöu chæïc nàng (scratch).
pwd
Âæa ra thæ muûc laìm viãûc (working directory hay folder) cuía SWI-Prolog.
ls
Liãût kã danh saïch caïc tãûp trong thæ muûc hiãûn haình.
edit
Nãúu Prolog âæåüc khåíi âäüng båíi mäüt tãûp .pl tæì trong Windows Explorer,
thç chaûy trçnh soaûn thaío màûc nhiãn, chàóng haûn Windows Notepad, âãø soaûn
thaío tãûp naìy. Coï thãø sæí duûng lãûnh âån File/Edit...
?- edit.
% Waiting for editor ...
...
Yes % Sau khi NSD kãút thuïc soaûn thaío
edit(+File)
Saûn thaío tãûp hay âån thãø chæång trçnh âaî coï màût trãn âéa.
?- edit(myex). % Måí Notepad âãø soaûn thaío tãûp myex.pl
% Waiting for editor ... % hiãûn coï åí thæ muûc hiãûn haình
...
Yes % Sau khi NSD kãút thuïc soaûn thaío
make
Naûp tãûp chæång trçnh vaìo bäü nhåï sau khi âaî thæûc hiãûn mäüt säú thay âäøi.
trace
Chaûy trçnh duyãût tçm sæía läùi debugger.
apropos(+Keyword)
Tçm vë tæì coï chæïa tæì khoaï Keyword.
help(+Spec)
Måí cæía säø hæåïng dáùn vãö Spec, laì tãn mäüt vë tæì hoàûc tãn mäüt haìm C.
Taì i liãû u tham khaí o
1. I. Bratko (L. Ricard dịch), Programmation en Prolog pour l’ intelligence artificielle,
InterÉditions, Paris, 1988.
2. I. Bratko, Programming for Artificial Intelligence, AddisonWesley, 1987.
3. K.L. Clavle, S.A. Tarnlound. Logic Programming. Accademic Press 1983.
4. G. Falquet. Prolog et programmation logique. Notes de cours, Université de Genève, 2002.
5. H. Farrenry, M. Ghallab. Éléments d’intelligence artificielle, Hermes, Paris-Londre-
Lausanne 1990.
6. Bạch Hưng Khang, Hoàng Kiếm. Trí tuệ nhân tạo : các phương pháp và ứng dụng. Nhà
Xuất bản Khoa học Kỹ thuật, 1989.
7. J.W. Leoyd. Foundations of Logic Programming, Springer-Verlag, 1984.
8. P. Nugues. La Programmation logique et le langage Prolog. Notes de cours, ISMRA, 2002.
9. D.Teller. Partiel de Prolog. Notes de cours, École Centrale de Lyons, 2001.
10. Nguyễn Thanh Thuỷ. Trí tuệ nhân tạo : các phương pháp giải quyết vấn đề và
kỹ thuật xử lý tri thức. Nhà Xuất bản Giáo dục, 1986.
11. A.Voronkov, Logic Programming and automated reasoning, Springer-Verlag, 1993.
12. Các tài liệu về Prolog và bài tập Prolog trên Internet :
ftp://ftp.umh.ac.be/pub/ftp_sgl/LangagesProgrammation/LP-exercProlog.pdf
http://www.etse.urv.es/EngInf/assig/iai/Laboratoris/Prolog/
http://membres.lycos.fr/epl2000/2eme/POO/
SPV_Prolog/1_Prolog_leLangage/
203