huong dan lap trinh prolog

35
1 Tröôøng Ñaïi hoïc Baùch Khoa TpHCM Khoa Coâng ngheä thoâng tin HÖÔÙNG DAÃN KYÕ THUAÄT LAÄP TRÌNH TURBO PROLOG 09/2001

Upload: te-ka

Post on 05-Dec-2014

55 views

Category:

Documents


6 download

DESCRIPTION

huong dan lap trinh prolog

TRANSCRIPT

1

Tröôøng Ñaïi hoïc Baùch Khoa TpHCM Khoa Coâng ngheä thoâng tin

HÖÔÙNG DAÃN KYÕ THUAÄT LAÄP TRÌNH TURBO PROLOG

09/2001

2

I. Vò töø (predicate) - Tö duy laäp trình vaø ñònh nghóa vaán ñeà treân Prolog Ñoái vôùi Prolog, moät chöông trình coù theå hieåu nhö laø caùc tri thöùc ñöôïc ngöôøi laäp trình cung caáp cho heä thoáng Prolog. Nhôø vaøo caùc kieán thöùc ñöôïc cung caáp, heä thoáng coù theå traû lôøi ñöôïc caùc caâu hoûi ñöôïc ñaët ra, vaø caâu traû lôøi coù theå ñaït ñöôïc nhôø cô cheá suy luaän cuûa heä thoáng döïa treân nhöõng kieán thöùc ñöôïc cung caáp ban ñaàu. Ñôn vò kieán thöùc maø ngöôøi laäp trình cung caáp cho Prolog goïi laø caùc vò töø (predicate). Caùc vò töø duøng ñeå bieåu dieãn caùc khaùi nieäm maø ngöôøi laäp trình muoán heä thoáng duøng ñeå suy luaän ñeå ñaït ñöôïc caùc kieán thöùc khaùc maø mình mong muoán. Veà maët kyõ thuaät, caùc predicate coù theå ñöôïc xem nhö caùc haøm, nhöng giaù trò traû veà chæ coù theå laø caùc giaù trò luaän lyù - ñuùng hoaëc sai. Vaø giaù trò traû veà naøy chæ coù theå söû duïng ñeå suy luaän, Prolog khoâng coù cô theá choàng chaát haøm nhö caùc ngoân ngöõ thuû tuïc khaùc, chính ñieàu naøy seõ laøm nhöõng ngöôøi quen vôùi vieäc laäp trình thuû tuïc gaëp khoù khaên khi böôùc ñaàu laäp trình vôùi Prolog. Coâng vieäc ñaàu tieân khi laäp trình treân Prolog laø ñònh nghóa caùc vò töø - caùc khaùi nieäm maø mình caàn cung caáp cho chöông trình. Xeùt caùc ví duï sau: VD1: Döõ kieän ban ñaàu: Moïi ngöôøi ñeàu phaûi cheát. Socrates laø ngöôøi. Yeâu caàu: Chuùng ta muoán heä thoáng phaûi coù khaû naêng suy luaän vaø traû lôøi ñöôïc caùc vaán ñeà lieân quan ñeán caùc khaùi nieäm treân: ai laø ngöôøi, ai khoâng laø ngöôøi, ai phaûi cheát, ai khoâng phaûi cheát. ÔÛ ñaây chuùng ta coù moät söï suy luaän thoâng minh ñaëc tröng cho söùc maïnh cuûa Prolog: heä thoáng seõ töï ñoäng suy luaän raèng Socrates phaûi cheát (ñieàu khoâng ñöôïc cung caáp ban ñaàu). Ñeå bieåu dieãn caùc vaán ñeà treân baèng ngoân ngöõ Prolog, chuùng ta caàn phaûi xaùc ñònh caàn phaûi bieåu dieãn nhöõng khaùi nieäm gì. Trong vaán ñeà naøy chuùng ta coù hai khaùi nieäm caàn bieåu dieãn: moät thöïc theå naøo ñoù coù theå laø ngöôøi (hoaëc khoâng), vaø moät thöïc theå naøo ñoù coù theå cheát. Nhö vaäy chuùng ta bieåu dieãn vaán ñeà ñaàu tieân baèng ngoân ngöõ Prolog nhö sau: nguoi(symbol)

3

Symbol laø moät kieåu döõ lieäu ñaëc bieät cuûa Prolog, duøng ñeå bieåu dieãn cho moät thöïc theå, moät khaùi nieäm toång quaùt. Chuùng ta seõ trôû laïi vaán ñeà naøy sau. Nhö vaäy chuùng ta vöøa ñònh nghóa moät khaùi nieäm: moät symbol naøo ñoù coù theå laø ngöôøi, moät symbol naøo khaùc thì khoâng. Hieåu nhö moät söï ñònh nghóa haøm, chuùng ta coù theå xem nhö ñònh nghóa moät haøm mang teân nguoi, haøm naøy coù thoâng soá moät bieán thuoäc kieåu döõ lieäu symbol, vaø keát quaû cuûa haøm naøy, khoâng caàn phaûi khai baùo thuoäc veà kieåu gì, vì chæ coù theå thuoäc kieåu boolean, chæ coù theå ñuùng hoaëc sai. Nhieäm vuï cuûa Prolog laø phaûi traû lôøi ñöôïc vôùi giaù trò symbol nhaäp vaøo, thì haøm naøy cho ra keát quaû ñuùng hoaëc sai, töùc symbol aáy coù phaûi laø ngöôøi hay khoâng. Prolog chæ coù theå laøm ñöôïc ñieàu naøy neáu nhö neáu nhö chuùng ta cung caáp cho heä thoáng moät cô cheá suy luaän ñuùng ñaén, töùc laø giaûi thích ñöôïc cho Prolog hieåu nhö theá naøo laø ngöôøi? Töông töï nhö vaäy, chuùng ta ñònh nghóa veà vaán ñeà moät thöïc theå naøo ñoù phaûi cheát baèng vò töø sau chet(symbol) Nhö vaäy vôùi baøi toaùn ñaõ neâu, chuùng ta seõ ñaët ra hai vò töø nguoi(symbol) chet(symbol) VD2: Yeâu caàu: tính giaù trò giai thöøa cuûa moät soá nguyeân baát kyø. Baøi toaùn treân khoâng cho bieát döõ kieän ban ñaàu. Chuùng ta phaûi cung caáp caùc döõ kieän ban ñaàu, ñeå Prolog coù theå döïa vaøo ñoù ñeå suy luaän, ñeå töø ñoù heä thoáng coù theå giaûi quyeát ñöôïc yeâu caàu cuûa chuùng ta. Vieäc cung caáp döõ kieän ban ñaàu cho heä thoáng laø raát quan troïng quyeát ñònh vaán ñeà giaûi quyeát yeâu caàu cuûa chuùng ta. Moät trong nhöõng caùch giaûi quyeát coù theå ñöôïc löïa choïn laø chuùng ta seõ cho heä thoáng bieát giaù trò giai thöøa cuûa toaøn boä soá nguyeân: giai thöøa cuûa 0 laø 1, giai thöøa cuûa 1 laø 1, giai thöøa cuûa 2 laø 2, giai thöøa cuûa 3 laø 6, giai thöøa cuûa 4 laø 24… Deã daøng nhaän thaáy raèng caùch naøy laø khoâng khaû thi, vaø trong thöïc teá, con ngöôøi cuõng khoâng tieáp thu tri thöùc theo caùch naøy.

4

Chuùng ta coù theå cung caáp döõ kieän cho heä thoáng theo caùch khaùc: giai thöøa cuûa moät soá laø tích caùc soá töø 1 ñeán soá ñoù. Nhö vaäy vôùi caùch giaûi quyeát naøy, chuùng ta coù hai khaùi nieäm caàn phaûi cung caáp: giai thöøa cuûa moät soá laø gì, vaø tích cuûa caùc soá nguyeân tính töø 1 ñeán moät soá laø gì? Caùch ñaët vaán ñeà naøy coù theå giaûi quyeát ñöôïc baøi toaùn, tuy nhieân chuùng ta coù theå ñaët vaán ñeà theo moät caùch khaùc ñôn giaûn, vaø hôïp vôùi tinh thaàn cuûa Prolog hôn: giai thöøa cuûa 0 laø 1, vaø giai thöøa cuûa moät soá lôùn hôn 0 laø giai thöøa cuûa soá lieàn tröôùc noù nhaân vôùi chính noù. Vôùi caùch ñaët vaán ñeà naøy, chuùng ta chæ coù moät khaùi nieäm phaûi bieåu dieãn: giai thöøa cuûa moät soá laø gì? (thaät ra chuùng ta coøn moät soá khaùi nieäm phaûi ñöa ra: moät soá ñöùng tröôùc moät soá laø gì, nhaân hai soá nghóa laø gì, tuy nhieân Prolog ñaõ cung caáp caùc toaùn töû ñeå giaûi quyeát vaán ñeà naøy. Hieåu theo moät nghóa naøo ñoù, caùc vaán ñeà treân laø caùc tieân ñeà, khoâng caàn phaûi giaûi thích vôùi heä thoáng.) Neáu quen vôùi ngoân ngöõ laäp trình thuû tuïc, chuùng ta coù khuynh höôùng khai baùo vò töø dieãn taû khaùi nieäm giai thöøa nhö sau: giaithua(integer) ÔÛ ñaây caùch ñaët vaán ñeà nhö vaäy laø khoâng thích hôïp vôùi ngoân ngöõ Prolog, vì . Moät vò töø chæ coù theå traû lôøi laø ñuùng hoaëc sai, trong khi chuùng ta ñang mong muoán keát quaû traû veà theo caùch khai baùo naøy moät soá . Ngoân ngöõ Prolog khoâng coù söï choàng chaát haøm, nghóa laø keát quaû cuûa haøm (vò töø) khoâng theå duøng nhö moät thoâng soá cho moät vò töø khaùc, trong khi chuùng ta ñang ñònh duøng keát quaû cuûa haøm naøy ñeå tính tieáp giaù trò cho moät haøm khaùc.(Chuùng ta ñònh duøng haøm naøy ñeå tính giai thöøa cuûa n -1 , roài nhaân tieáp cho n ñeå ra keát quaû cuoái cuøng). Vò töø thích hôïp seõ ñöôïc khai baùo nhö sau: giaithua(integer,integer) Ñieàu naøy, hieåu theo ngoân ngöõ thuû tuïc, nghóa laø chuùng ta khai baùo moät haøm coù thoâng soá laø hai soá nguyeân, vaø keát quaû traû veà seõ laø ñuùng hoaëc sai. Ñieàu chuùng ta muoán dieãn taû coù nghóa laø: giai thöøa cuûa moät soá nguyeân (integer) seõ laø moät soá nguyeân khaùc.

5

Neáu chuùng ta giaûi thích ñöôïc cho Prolog hieåu giai thöøa cuûa moät soá nguyeân seõ ñöôïc tính nhö theá naøo, heä thoáng seõ coù khaû naêng traû lôøi cho caû caâu hoûi thuaän (giai thöøa cuûa moät soá nguyeân laø gì), caâu hoûi nghòch (soá nguyeân naøo coù giai thöøa baèng soá nguyeân naøy), vaø nghi vaán (giai thöøa cuûa moät soá nguyeân X coù phaûi laø soá nguyeân Y hay khoâng). Tuy nhieân muïc ñích cuûa chuùng ta chæ cung caáp caùc döõ kieän ñeå heä thoáng coù theå traû lôøi caâu hoûi thuaän (vaø coù theå traû lôøi theâm caâu hoûi nghi vaán) maø thoâi. Toùm taét: . Laäp trình treân Prolog laø cung caáp cho heä thoáng caùc khaùi nieäm vaø dieãn giaûi caùc khaùi nieäm ñoù. . Caùc khaùi nieäm ñöôïc cung caáp qua caùc vò töø. . Caùc vò töø coù theå xem nhö caùc haøm nhö chæ traû veà giaù trò ñuùng hoaëc sai. . Vieäc heä thoáng coù theå traû lôøi ñöôïc nhöõng caâu hoûi naøo lieân quan ñeán khaùi nieäm ñaõ cung caáp phuï thuoäc vaøo vieäc chuùng ta dieãn giaûi caùc khaùi nieäm treân cho heä thoáng

6

II. Caùc clause, caùch giaûi thích caùc vaán ñeà treân Prolog Sau khi ñaõ cung caáp cho heä thoáng caùc khaùi nieäm caàn thieát, chuùng ta caàn phaûi giaûi thích caùc khaùi nieäm mình ñaõ cung caáp, Prolog seõ duøng caùc lôøi giaûi thích naøy ñeå thöïc hieän vieäc suy luaän vaø traû lôøi caâu hoûi cuûa chuùng ta. Caùc lôøi giaûi thích naøy ñöôïc goïi laø caùc meänh ñeà (clauses). Coù hai daïng meänh ñeà: söï kieän (fact), vaø luaät( rule) Caùc söï kieän laø nhöõng ñieàu maø chuùng ta coâng nhaän laø ñuùng. Luaät laø nhöõng quy taéc maø chuùng ta xaùc ñònh ñieàu kieän ñuùng cho chuùng. VD3: haõy vieát phaàn clause cho vò töø nguoi ñaõ ñònh nghóa trong VD1 Döõ kieän ban ñaàu chæ cung caáp cho chuùng ta moät vaán ñeà lieân quan ñeán ngöôøi: Socrates laø ngöôøi. Theo nhö caùch tö duy trong khoâng gian cuûa baøi toaùn, chæ coù moät con ngöôøi duy nhaát: Socrates. Khoâng ai khaùc laø ngöôøi. Nhö vaäy chuùng ta seõ vieát phaàn clause cho vò töø naøy nhö sau: nguoi(socrates). Chuùng ta vöøa vieát moät söï kieän: socrates laø ngöôøi laø ñieàu chaéc chaén ñuùng. Baát kyø symbol naøo coù teân laø socrates laø ngöôøi laø chaéc chaén ñuùng, khoâng caàn phaûi coù moät ñieàu kieän raøng buoäc naøo keøm theo. Löu yù: i/Coù hai caùch vieát daïng haèng (literal) cho symbol treân Prolog: . Moät danh hieäu môû ñaàu baèng kyù töï thöôøng (socrates, sOCRATES…)

. Moät chuoãi kyù hieäu ñaët trong caëp kyù hieäu "," ("socrates","SOCRATES"," sOCRATES", "Socrates"…)

ii/ moät meänh ñeà luoân keát thuùc baèng kyù töï '.' VD4: haõy vieát phaàn clause cho vò töø chet trong VD1.

7

Döõ kieän ban ñaàu chæ cung caáp cho chuùng ta moät söï kieän lieân quan ñeán vaán ñeà naøy: symbol seõ phaûi cheát neáu (vaø chæ neáu) ñoù laø ngöôøi. Ñieàu naøy seõ xaùc ñònh moät quy taéc: symbol seõ chæ phaûi cheát, töùc vò töø seõ traû veà keát quaû true, neáu symbol ñoù laø ngöôøi. Vaán ñeà symbol naøo laø ngöôøi vaø symbol naøo khoâng laø ngöôøi chuùng ta ñaõ ñöa ra khaùi nieäm vaø giaûi thích cho Prolog trong caùc ví duï 1 vaø 3. Nhö vaäy phaàn meänh ñeà seõ ñöôïc vieát nhö sau; chet(X):-nguoi(X). Meänh ñeà daïng rule seõ bao goàm hai phaàn, naèm ôû hai beân caëp kyù hieäu ":-". Phaàn beân traùi cho bieát vò töø ñang ñöôïc ñeà caäp vaø caùc thoâng soá töông öùng. Phaàn beân phaûi, xaùc ñònh ñieàu kieän traû lôøi ñuùng cho luaät treân, bao goàm caùc lôøi goïi caùc vò töø khaùc, ñöôïc ngaên caùch bôûi kyù hieäu ',', goïi laø caùc meänh ñeà con (sub-clause). Trong ví duï treân, chæ coù moät sub-clause. Moät luaät chæ traû lôøi ñuùng neáu taát caû caùc sub-clause beân veá phaûi ñeàu traû lôøi ñuùng. Trong ví duï treân, chuùng ta coù moät bieán X. Taát caû caùc thoâng soá môû ñaàu baèng kyù töï hoa ñeàu ñöôïc Prolog hieåu laø bieán. Bieán naøy laø thoâng soá cuûa vò töø chet. Do ñaõ khai baùo ôû phaàn vò töø, X seõ ñöôïc hieåu laø moät bieán thuoäc kieåu symbol. Keát quaû seõ traû veà ñuùng neáu taát caû sub-clause beân veá phaûi ñeàu traû lôøi laø ñuùng. Trong tröôøng hôïp naøy, chæ coù moät sub-clause xaùc ñònh xem X coù phaûi laø ngöôøi khoâng. Nhö vaäy chuùng ta ñaõ bieåu dieãn ñöôïc khaùi nieäm moät symbol seõ phaûi cheát neáu symbol ñoù laø ngöôøi, töùc laø taát caû nhöõng döõ kieän ban ñaàu ñöôïc cung caáp. VD5: Haõy vieát phaàn clause cho vò töø giaithua ôû VD2. Töø caùc döõ kieän ñöôïc cung caáp (do chuùng ta töï cung caáp cho mình ñeå giaûi baøi toaùn), chuùng ta thaáy coù moät söï kieän chaéc chaén ñuùng: giai thöøa cuûa 0 laø 1, vaø coù moät luaät suy dieãn: giai thöøa cuûa n laø (n-1)!*n. Chuùng ta seõ vieát phaàn meänh ñeà cho vò töø naøy nhö sau: giaithua(0,1). giaithua(X,Y) -: X1 = X -1, giaithua(X1,Y1), Y = Y1*X. Tröôùc khi hieåu nhöõng ñieàu ñöôïc moâ taû trong caùc ví duï treân, chuùng ta seõ coù moät soá nhaän xeùt nhö sau: i./Tröôùc tieân, chuùng ta thaáy vò töø giaithua ñöôïc bieåu dieãn baèng hai meänh ñeà: moät söï kieän vaø moät luaät.

8

Khi vieát nhieàu meänh ñeà cho moät vò töø, caùc meänh ñeà phaûi ñöôïc vieát lieân tieáp nhau (khoâng ñöôïc xen meänh ñeà cuûa vò töø khaùc vaøo). ii./ Chuùng ta seõ hieåu hai meänh ñeà con ñaàu tieân X1 = X -1, giaithua(X1,Y1) bieåu dieãn cho coâng vieäc tính giai thöøa cuûa X-1. Tuy nhieân chuùng ta khoâng ñöôïc vieát giaithua(X-1,Y1). Thoâng soá cuûa caùc meänh ñeà con phaûi laø bieán, khoâng ñöôïc pheùp laø bieåu thöùc. iii./ Chuùng ta thaáy söï xuaát hieän cuûa kyù hieäu '= ' vaø seõ hieåu nhö meänh ñeà con X1 = X-1 laø pheùp gaùn. Treân Prolog khoâng coù pheùp gaùn. Kyù hieäu '=' bieåu dieãn cho moät pheùp toaùn ñaëc bieät cuûa Prolog, pheùp hôïp nhaát (unification), vaø cuõng nhö caùc meänh ñeà khaùc, pheùp hôïp nhaát naøy seõ traû veà keát quaû ñuùng hoaëc sai, bieåu dieãn cho keát quaû coâng vieäc hôïp nhaát thaønh coâng hay khoâng. Xem theâm veà pheùp hôïp nhaát trong caùc phaàn sau. iv./ Phaàn vò töø treân bieåu dieãn cho vieäc söû duïng kyõ thuaät laäp trình ñeä quy, seõ laø söùc maïnh laäp trình chuû yeáu cuûa Prolog. Xem theâm veà phaàn laäp trình ñeä quy treân Prolog trong caùc phaàn sau. Toùm taét . Caùc khaùi nieäm ñöôïc moâ taû qua caùc vò töø seõ ñöôïc giaûi thích baèng caùc meänh ñeà. . Coù hai loaïi meänh ñeà: söï kieän vaø luaät. . Thoâng soá ñöôïc truyeàn trong lôøi goïi caùc meänh ñeà con phaûi laø bieán. . Caùc kyõ thuaät chuû yeáu ñeå laäp trình treân Prolog laø hôïp nhaát vaø ñeä quy.

9

III. Thöïc thi chöông trình. - Ñaët caâu hoûi vaø nhaän caâu traû lôøi Ñeán ñaây chuùng ta ñaõ coù theå thöïc thi caùc chöông trình treân. Treân cöûa soå Prolog, nhaäp noäi dung ñoaïn chöông trình vaøo vuøng cöûa soå soaïn thaûo. (Chuùng ta coù theå luoân chuyeån veà vuøng cöûa soå naøy baèng phím noùng Alt+E) VD6: Vieát chöông trình hoaøn chænh cho VD1. Noäi dung chöông trình nhaäp hoaøn chænh cho VD1 nhö sau: predicates nguoi(symbol) chet(symbol) clauses nguoi("Socrates"). chet(X):-nguoi(X). Nhö vaäy chuùng ta thaáy trong moät chöông trình Prolog, caùc phaàn khai baùo caùc vò töø vaø hieän thöïc caùc meänh ñeà ñöôïc baét ñaàu baèng caùc töø khoaù predicates vaø clauses. Löu yù:Phaàn predicates phaûi ñöôïc vieát tröôùc phaàn daønh cho clauses Chuùng ta söû duïng Turbo Prolog ñeå thöû caùc ví duï treân

10

Giao dieän chöông trình seõ nhö sau:

Ñeå thöïc thi chöông trình, ngöôøi söû duïng nhaäp yeâu caàu (caâu hoûi) cuûa mình cho heä thoáng. Yeâu caàu naøy goïi laø goal. Coù hai loaïi goal:goal noäi vaø goal ngoaïi. Phaàn naøy chæ trình baøy veà goal ngoaïi. Ñeå nhaäp goal ngoaïi, sau khi ñaõ hoaøn taát vieäc soaïn thaûo chöông trình, chuùng ta duøng phím taét Alt+R ñeå chuyeån sang vuøng giao tieáp cuûa chöông trình. Caâu hoûi chuùng ta ñaët ra cho heä thoáng phaûi chæ döïa vaøo caùc tri thöùc maø chuùng ta ñaõ cung caáp cho heä thoáng. Chuùng ta ñaõ cung caáp cho heä thoáng caùc khaùi nieäm nguoi vaø chet, nhö vaäy chuùng ta chæ coù theå ñaët caùc caâu hoûi lieân quan ñeán hai khaùi nieäm naøy. Ngay sau daáu nhaéc Goal: taïi vuøng cöûa soå naøy, chuùng ta coù theå nhaäp caâu hoûi nhö sau: nguoi("Socrates") Döïa treân tinh thaàn cuûa cuûa khaùi nieäm, caâu phaùt bieåu cuûa chuùng ta coù nghóa laø "Socrates laø ngöôøi", vaø vì ñaây laø caâu phaùt bieåu trong vuøng goal, neân heä thoáng seõ hieåu raèng chuùng

Vuøng soaïn thaûo (aán Alt+E ñeå chuyeån ñeán vuøng naøy khi dang ôû caùc vuøng cöûa soå khaùc)

Vuøng giao tieâp (aán Alt+R) ñeå thöïc thi chöông trình khi soaïn thaûo xong chöông trình

Nhaäp goal (ngoaïi) vaøo ñaây

11

ta muoán ñaët moät caâu hoûi nghi vaán "Socrates laø ngöôøi phaûi khoâng?" Sau khi aán Enter, chuùng ta seõ thaáy heä thoáng coù ngay caâu traû lôøi: Yes. Thay baèng moät teân khaùc, ví duï: nguoi("Xeda") Heä thoáng seõ traû lôøi No. Chuùng ta thaáy caùc caâu traû lôøi cuûa heä thoáng döïa treân kieán thöùc maø chuùng ta ñaõ cung caáp. Döïa vaøo nhöõng gì maø chuùng ta ñaõ cung caáp, heä thoáng chæ bieát coù moät ngöôøi laø Socrates, taát caû nhöõng symbol khaùc ñeàu khoâng phaûi laø ngöôøi. Tuy nhieân, vôùi cô cheá suy luaän maø chuùng ta cung caáp, heä thoáng coù theå suy luaän ra nhöõng ñieàu chöa ñöôïc cung caáp saún. Ñaây chính laø ñieåm taïo neân söùc maïnh laäp trình cuûa Prolog. Nhaäp vaøo goal nhö sau: chet("Socrates") Caâu traû lôøi laø: Yes. Vôùi moät teân ngöôøi khaùc: chet("Xeda") Caâu traû lôøi laø: No. Heä thoáng ñaõ töï ñoäng suy luaän theo nguyeân lyù maø chuùng ta muoán noù phaûi "hoïc": ai laø ngöôøi thì ngöôøi ñoù phaûi cheát. Ngoaøi nhöõng caâu hoûi daïng Yes/No, Prolog coù theå traû lôøi caùc caâu hoûi yeâu caàu tìm ñaùp soá. Chuùng ta nhaäp vaøo moät goal nhö sau: chet(X)

12

Ñeán ñaây, trong caâu hoûi cuûa chuùng ta coù moät bieán: X (nhaéc laïi: moïi danh hieäu môû ñaàu laø kyù töï hoa ñeàu laø bieán). Khi trong caâu hoûi cuûa chuùng ta chöùa moät (hoaëc nhieàu) bieán, heä thoáng seõ tìm caùc giaù trò coù theå coù cuûa bieán ñeå cho caâu phaùt bieåu cuûa ta laø ñuùng. Hieåu ôû möùc yù nieäm, caâu hoûi cuûa chuùng ta laø: ai laø ngöôøi? Keát quaû traû lôøi cuûa caâu hoûi (ai) seõ ñöôïc chöùa trong bieán X. Caâu traû lôøi seõ laø: X = Socrates Töông töï nhö treân, heä thoáng seõ döïa vaøo cô cheá suy luaän ñaõ ñöôïc cung caáp ñeå tìm ra lôøi giaûi vôùi nhöõng caâu hoûi daønh cho caùc vò töø coù caùc meänh ñeà töông öùng laø caùc luaät. Nhaäp vaøo goal nhö sau: chet(X) Heä thoáng seõ traû lôøi nhö sau: X = Socrates. VD7: Hoaøn chænh vaø thöïc thi chöông trình cho VD2 Chöông trình hoaøn chænh nhö sau: predicates giaithua(integer,integer) clauses giaithua(0,1). giaithua(X,Y):- X1 = X -1, giaithua(X1,Y1), Y = X*Y1. Chuùng ta löu yù laø khi keát thuùc moãi meänh ñeà ñeàu coù kyù hieäu '.' Chuùng ta coù theå ñaët cho heä thoáng goal daïng nghi vaán nhö sau: giaithua(3,6) Hieåu theo ngoân ngöõ töï nhieân seõ laø: coù phaûi giai thöøa cuûa 3 laø 6 hay khoâng? Caâu traû lôøi laø: Yes Hoaëc chuùng ta coù theå ñaët caâu hoûi: giaithua(3,8)

13

Caâu traû lôøi seõ laø: No. Chuùng ta seõ ñaët caâu hoûi theo daïng tìm lôøi giaûi: giaithua(3,X) Caâu traû lôøi seõ laø X = 6 Chuùng ta cuõng coù theå ñaët caâu hoûi ngöôïc: giaithua(X,6) YÙ töôûng cuûa caâu hoûi seõ laø: giai thöøa cuûa soá naøo seõ baèng 6. Tuy nhieân chuùng ta khoâng cung caáp cho heä thoáng cô cheá suy luaän ñeå traû lôøi caâu hoûi naøy. Heä thoáng seõ traû lôøi: No Solution. Taát nhieân chuùng ta coù theå ñaët caâu hoûi nhö sau: giaithua(X,Y) Caû hai thoâng soá ñeàu laø bieán. Nhö vaäy caâu hoûi coù theå hieåu laø: soá naøo (X) giai thöøa thì thaønh moät soá khaùc (Y). Caâu hoûi gaàn nhö voâ nghóa vaø nhöõng caâu traû lôøi cuûa heä thoáng cuõng seõ chaúng mang moät yù nghóa thöïc söï coù nghóa naøo. Toùm taét: . Chöông trình Prolog seõ hoaït ñoäng theo cô cheá töông taùc. Ngöôøi söû duïng seõ cung caáp yeâu caàu, goïi laø goal, vaø heä thoáng seõ traû lôøi caùc yeâu caàu naøy. . Coù hai loaïi goal: goal noäi vaø goal ngoaïi. . Neáu goal khoâng chöùa bieán thì heä thoáng seõ kieåm tra phaùt bieåu cuûa chuùng ta laø ñuùng hoaëc sai, ngöôïc laïi, heä thoáng seõ tìm caùc giaù trò cuûa caùc bieán laøm cho phaùt bieåu cuûa ta laø ñuùng.

14

IV. Pheùp hôïp nhaát - Cô cheá tìm caâu traû lôøi cuûa Prolog. Pheùp hôïp nhaát Coâng vieäc quan troïng nhaát cuûa Prolog trong vieäc tìm caâu traû lôøi laø thöïc hieän vieäc hôïp nhaát. Pheùp hôïp nhaát ñöôïc bieåu dieãn baèng daáu =, vaø noù coù hai thaønh phaàn, taïm goïi laø veá traùi veá phaûi. Pheùp hôïp nhaát seõ traû veà keát quaû true hoaëc false Coù caùc tröôøng hôïp hôïp nhaát sau: a. Caû hai veá ñeàu laø haèng hoaëc bieåu thöùc chöùa toaøn haèng. Neáu giaù trò cuûa hai veá laø baèng nhau thì pheùp hôïp nhaát thaønh coâng (ñaùp soá laø true), ngöôïc laïi pheùp hôïp nhaát seõ thaát baïi (keát quaû laø false) 7 = 7 true 7 = 8 false "abc" = "abc" true "abcd" = "abc" false 7 = 6 +1 true 6 = 7 +1 false b. Moät trong hai veá laø haèng hoaëc trong bieåu thöùc chöùa toaøn haèng, veá kia laø bieán hoaëc bieåu thöùc coù chöùa bieán. . Tröôøng hôïp 1: Neáu taát caû caùc bieán ñeàu coù giaù trò (goïi laø caùc bieán ôû tình traïng bound), chuùng ta quay veà tröôøng hôïp a 7 = X false neáu X ñaõ coù giaù trò laø 6 7 = X +1 true neáu X ñaõ coù giaù trò laø 6 Y = "Socrates" true neáy Y ñaõ coù giaù trò laø "Socrates" . Tröôøng hôïp 2: Neáu coù bieán chöa coù giaù trò (goïi laø bieán ôû tình traïng unbound), Prolog seõ gaùn giaù trò cho bieán sau cho hai veá coù giaù trò nhö nhau vaø traû veà keát quaû laø true. Neáu khoâng tìm giaù trò nhö vaäy, pheùp hôïp nhaát seõ cho keát quaû laø false. 7 = X true neáu X chöa coù giaù trò, sau pheùp hôïp nhaát naøy, X seõ coù giaù trò laø 7 -1 = X*X false vì khoâng theå tìm cho X giaù trò naøo laøm cho giaù trò hai veá laø nhö nhau.

c. Caû hai veá ñeàu laø bieán hoaëc caùc bieåu thöùc coù chöùa bieán

15

. Tröôøng hôïp 1: taát caû caùc bieán ñeàu coù chöùa giaù trò, chuùng ta seõ quay veà tröôøng hôïp a

X = Y true neáu caû X vaø Y ñeàu ñaõ coù giaù trò vaø nhöõng giaù trò naøy baèng nhau X -1 = Y false neáu X vaø Y ñeàu ñaõ coù giaù trò vaø X nhoû hôn Y . Tröôøng hôïp 2: taát caû caùc bieán cuûa moät veá ñeàu ñaõ coù giaù trò, chuùng ta seõ quay

veà veà tröôøng hôïp b X = Y true neáu X chöa coù giaù trò vaø Y ñaõ coù giaù trò, sau pheùp hôïp nhaát, X seõ

nhaän giaù trò cuûa Y X - 1 = Y true neáu X chöa coù giaù trò, Y ñaõ coù giaù trò. Sau pheùp hôïp nhaát, X

seõ coù giaù trò baèngg Y +1 . Tröôøng hôïp 3: caû hai veá ñeàu coøn chöùa bieán ôû tình traïng unbound hôïp nhaát

thaát baïi X = Y false neáu caû X vaø Y ñeàu chöa gaùn giaù trò X-1 = Y false neáu caû X vaø Y ñeàu chöa gaùn giaù trò

Cô cheá tìm caâu traû lôøi cuûa Prolog Neáu chuùng ta ñaët ra cho Prolog moät caâu hoûi, Prolog seõ thöïc hieän coâng vieäc so truøng (match), töùc laø tìm meänh ñeà ñaàu tieân ñeà caäp ñeán khaùi nieäm maø chuùng ta muoán hoûi. Trôû laïi VD6, sau khi ñaõ hoaøn taát chöông trình, chuùng ta ñaët ra Goal nhö sau: nguoi("Socrates") Prolog seõ tìm meänh ñeà ñaàu tieân coù lieân quan ñeán khaùi nieäm nguoi. Hieån nhieân, meänh ñeà ñaàu tieân (vaø duy nhaát coù lieân quan ñeán khaùi nieäm naøy laø: nguoi("Socrates") Nhö vaäy, khi ñaõ coù goal (nguoi("Socrates")) vaø tìm thaáy meänh ñeà lieân quan (nguoi("Socrates")), Prolog seõ tieán haønh tìm kieám lôøi giaûi, coâng vieäc naøy tieán haønh baèng caùch taïo moái lieân keát giöõa caùc thoâng soá ôû phaàn goal vaø caùc thoâng soá ôû phaàn meänh ñeà. Coù caùc tröôøng hôïp sau: a. Caû hai thoâng soá naøy ñeàu laø caùc bieán unbound, trong tröôøng hôïp naøy Prolog seõ xem caû hai thoâng soá laø 1.

16

b. ÔÛ taát caû caùc tröôøng hôïp khaùc, Prolog seõ tieán haønh pheùp hôïp nhaát giöõa hai loaïi thoâng soá. Sau khi ñaõ taïo moái quan heä giöõa caùc thoâng soá ôû phaàn goal vaø phaàn clause, Prolog seõ tieán haønh caùc sub-clause (neáu meänh ñeà naøy moät luaät). Neáu taát caû caùc sub-clause thaønh coâng vaø caùc bieán ôû phaàn goal ñaõ ôû tình traïng bound (töùc laø ñaõ coù giaù trò), Prolog seõ thoâng baùo lôøi giaûi. Neáu laø caâu hoûi thuoäc daïng Yes/No nhö ví duï treân, töùc laø caâu hoûi khoâng chöùa bieán, Prolog seõ traû lôøi Yes neáu coâng vieäc hôïp nhaát nhö ñaõ noùi ôû phaàn b thaønh coâng vaø caùc sub-clause ñeàu thaønh coâng (neáu meänh ñeà so truøng laø moät luaät). Quay trôû laïi vôùi ví duï cuûa chuùng ta, ôû ñaây thoâng soá cuûa Goal laø moät haèng ("Socrates), vaø thoâng soá cuûa meänh ñeà töông öùng cuõng laø moät haèng ("Socrates), hai haèng naøy hôïp nhaát thaønh coâng, vaø keát quaû traû lôøi laø Yes. Neáu chuùng ta ñaët ra caâu hoûi khaùc: nguoi("Xeda") Prolog cuõng chæ tìm thaáy moät meänh ñeà lieân quan ñeán khai nieäm naøy (nguoi("Socrates")), vaø vì söï hôïp nhaát giöõa hai haèng "Socrates" vaø "Xeda" thaát baïi, ñaùp soá seõ traû lôøi laø No. Chuùng ta xeùt tröôøng hôïp caâu hoûi cuûa chuùng ta coù chöùa bieán: nguoi(X) Heä thoáng seõ tìm thaáy meänh ñeà coù lieân quan ñeán vaán ñeà naøy (nguoi("Socrates")) , vaø tieán haønh hôïp nhaát giöõa X vaø "Socrates", vaø vì X chöa coù giaù trò (unbound) neân pheùp hôïp nhaát thaønh coâng, X coù giaù trò laø "Socrates". Vì vieäc hôïp nhaát giöõa caùc thoâng soá giöõa phaàn goal vaø phaàn clause ñaõ thaønh coâng, ñaây laø moät söï kieän neân khoâng caàn phaûi thöïc hieän phaàn sub-clause, vaø sau khi hôïp nhaát, taát caû caùc bieán caàn tìm ñaõ coù giaù trò (ôû ñaây chæ coù moät bieán laø X), neân heä thoáng seõ coâng boá ñaõ tìm ra lôøi giaûi vaø in ra giaù trò cuûa X ( X = "Socrates") Chuùng ta xeùt tröôøng hôïp khi ôû caâu hoûi phaàn goal so truøng vôùi moät luaät: chet(Y)

17

Chuùng ta hoaøn toaøn coù theå ñaët caâu hoûi laø chet(X), nhöng chuùng ta seõ ñaët teân bieán khaùc ñeå tieän phaân bieät giöõa bieán trong caâu hoûi cuûa goal vaø thoâng soá cuïc boä ôû meänh ñeà. Caâu hoûi trong goal ñöôïc so truøng vôùi meänh ñeà sau: chet(X): - nguoi (X). Vì hai bieán X(thoâng soá cuûa meänh ñeà) vaø Y(thoâng soá cuûa goal) ñeàu chöa chöùa giaù trò, heä thoáng seõ xem caû hai bieán laø moät, töùc laø, khi X coù ñöôïc giaù trò thì Y cuõng coù giaù trò ñoù vaø ngöôïc laïi. Do ñaây laø moät luaät, neân heä thoáng seõ tieán haønh thöïc hieän caùc sub-clause. Heä thoáng seõ thöïc hieän sub-clause ñaàu tieân nguoi(X). Quaù trình thöïc hieän caùc sub-clause ôû veá phaûi seõ ñöôïc thöïc hieän nhö sau: a. Neáu sub-clause naøy coù thoâng soá laø bieán unbound, Prolog seõ tìm giaù trò cuûa bieán naøy ñeå sub-clause coù giaù trò Yes, neáu khoâng tìm ñöôïc giaù trò nhö vaäy, sub-clause seõ thaát baïi. b. Neáu sub-clause coù thoâng soá ñeàu laø bieán bound (ñaõ coù giaù trò) hoaëc laø haèng, Prolog seõ kieåm tra xem sub-clause coù traû veà giaù trò Yes hay khoâng, neáu khoâng, sub-clause seõ thaát baïi. Caùc sub-clause seõ ñöôïc tieán haønh töø traùi qua phaûi, vaø neáu coù moät sub-clause thaát baïi, meänh ñeà ñöôïc so truøng seõ thaát baïi. Trong tröôøng hôïp treân, khi tieán haønh sub-clause nguoi(X), do bieán X laø unbound, neân chuùng ta rôi vaøo tröôøng hôïp a, heä thoáng seõ tìm giaù trò cuûa X cho sub-clause treân laø ñuùng. Caùch tìm kieám caâu traû lôøi cho sub-clause naøy hoøan toøan gioáng nhö caùch heä thoáng tìm caâu traû lôøi khi chuùng ta ñaët caâu hoûi naøy trong phaàn goal, vaø nhö vaäy X seõ coù giaù trò laø "Socrates" sau khi sub-clause naøy thöïc hieän xong. Do X vaø Y ñöôïc xem nhö moät, neân khi X coù giaù trò laø "Socrates" thì Y cuõng coù giaù trò naøy. Do taát caû caùc sub-clause ñaõ thöïc hieän xong, vaø Y ñaõ coù giaù trò, neân Prolog coâng boá laø ñaõ tìm ra lôøi giaûi vaø in ra giaù trò cuûa Y. Toùm taét:

18

. Pheùp hôïp nhaát laø neàn taûng cuûa moïi hoaït ñoäng cuûa Prolog ñeå tìm ra lôøi giaûi

. Ñeå traû lôøi caâu hoûi, Prolog so truøng caâu hoûi vôùi meänh ñeà vaø taïo moái lieân quan giöõa caùc thoâng soá. . Prolog tìm ra lôøi giaûi khi thöïc hieän thaønh coâng moät meänh ñeà vaø taát caû caùc bieán neáu coù trong caùc thoâng soá cuûa goal ñeàu ñaõ coù giaù trò

19

V. Söï quay lui - Khoáng cheá soá löôïng lôøi giaûi -Vò töø nhaùt caét vaø fail Goal noäi vaø goal ngoaïi (internal goal vaø external goal) Khi chuùng ta söû duïng Alt-R ñeå chuyeån sang cöûa soå giao tieáp vaø nhaäp vaøo goal, goal naøy goïi laø goal ngoaïi. Chuùng ta coù theå theâm phaàn goal naøy haún trong phaàn soaïn thaûo chöông trình, goal naøy goïi laø goal noäi. VD8: Vieát laïi chöông trình giaûi quyeát VD6 söû duïng goal noäi Chöông trình ñöôïc vieát laïi nhö sau: predicates nguoi(symbol) chet(symbol) clauses nguoi("Socrates"). chet(X):-nguoi(X). goal nguoi(X),write(X) Trong ví duï naøy, chuùng ta ñaõ theâm phaàn goal vaøo trong chöông trình. Khi thöïc thi, heä thoáng seõ khoâng hoûi goal nöõa, vaø töï ñoäng thöïc hieän caùc yeâu caàu trong phaàn goal. Tuy nhieân khi thöïc hieän goal noäi, heä thoáng seõ khoâng töï ñoäng in keát quaû nöõa. Chuùng ta phaûi goïi vò töø write ñeå laøm ñieàu naøy. Vò töø naøy seõ cho keát quaû laø ñuùng neáu caùc thoâng soá nhaäp vaøo laø ñeàu laø bieán ôû traïng thaùi bound hoaëc laø haèng. Söï quay lui (back-tracing) treân Prolog Hôïp nhaát laø hoøn ñaù neàn taûng cho cô cheá suy luaän cuûa Prolog, tuy nhieân, ñeå tìm ra lôøi giaûi ñuùng, Prolog phaûi söû duïng cô cheá quay lui, khi giaù trò ñaàu tieân ñöôïc gaùn cho thoâng soá khoâng phaûi laø lôøi giaûi. Chuùng ta xeùt ví duï sau: VD9: predicates nguoi(symbol)

20

vua(symbol) sungsuong(symbol) clauses nguoi("Socrates").

nguoi("Xeda"). vua("Xeda). sungsuong(X) :- nguoi(X),vua(X).

Nhö vaäy trong ví duï naøy, ngoaøi khaùi nieäm veà ngöôøi, chuùng ta ñöa ra khaùi nieäm veà vua vaø söï sung söôùng. Dieãn giaûi nhöõng thoâng tin trong caùc döõ kieän treân thaønh ngoân ngöõ töï nhieân, chuùng ta coù ñöôïc caùc ñieàu sau: "Theá giôùi maø chuùng ta soáng coù hai ngöôøi laø Socrates vaø Xeda. Chuùng ta coù moät vua la Xeda, vaø moät thöïc theå naøo ñoù chæ sung söôùng neáu thöïc theå ñoù vöøa ngöôøi vöøa laø vua." Löu yù raèng trong ví duï treân, caùc meänh ñeà lieân quan ñeán cuøng moät vò töø phaûi vieát lieân tieáp nhau. Xeùt khi heä thoáng traû lôøi caâu hoûi sau: sungsuong(X) Tröôùc tieân heä thoáng seõ so truøng goal treân vôùi meänh ñeà sungsuong(X) :- nguoi(X),vua(X). Löu yù raèng vaøo luùc naøy chuùng ta coù hai bieán X: moät bieán X laø thoâng soá cuûa goal vaø moät bieán X laø thoâng soá cuûa meänh ñeà. Veà nguyeân taéc, hai bieán X naøy hoøan toøan khaùc nhau. Tuy nhieân, khi so truøng goal vôùi meänh ñeà, do caû hai bieán X luùc naøy ñeàu chöa chöùa giaù trò, neân chuùng seõ ñöôïc xem nhö moät. Nhöng caàn chuù yù raèng bieán X söû duïng trong caùc sub-clause laø bieán X thoâng soá cuûa meänh ñeà. Sau ñoù Prolog seõ tieán haønh caùc sub-clause. ÔÛ sub-clause ñaàu tieân, nguoi(X), töông töï nhö VD6, Prolog seõ tìm ñöôïc caâu traû lôøi laø X = Socrates. Khi thöïc hieän sub-clause thöù hai, vua(X), do X ñaõ coù giaù trò (Socrates), Prolog seõ kieåm tra xem giaù trò naøy coù laøm giaù trò cuûa meänh ñeà laø true hay khoâng. Nhö caùc ví duï treân, vieäc tieán haønh traû lôøi moät sub-clause cuõng töông töï nhö khi traû lôøi moät goal, Prolog laïi so truøng sub-clause vôùi moät meänh ñeà cuøng teân. Prolog tìm thaáy moät meänh ñeà lieân quan ñeán vua laø vua("Xeda") vaø tieán haønh hôïp nhaát giöõa X vaø Xeda. Do X ñaõ coù giaù trò laø Socrates, vieäc hôïp nhaát thaát baïi.

21

Tuy nhieân khi sub-clause naøy thaát baïi, khoâng coù nghóa raèng Prolog seõ voäi keát luaän raèng meänh ñeà naøy thaát baïi. ÔÛ ñaây coâng vieäc tìm kieám caâu traû lôøi thaát baïi sau khi bieán X ñöôïc gaùn giaù trò vaø chuyeån töø traïng thaùi bound sang unbound. Heä thoáng seõ quay laïi thôøi ñieåm bieán X ñöôïc gaùn giaù trò (khi traû lôøi sub-clause nguoi(X)) , X ñöôïc chuyeån laïi sang tình traïng unbound, vaø coá gaéng tìm kieám moät giaù trò khaùc cuûa X ñeå cho meänh ñeà con naøy vaån ñuùng. Coâng vieäc naøy ñöôïc goïi laø back-tracing. Do vieäc so truøng sub-clause naøy vôùi meänh ñeà nguoi("Socrates") thaát baïi, heä thoáng seõ so truøng vôùi meänh ñeà khaùc. Neáu khoâng coøn meänh ñeà naøo khaùc lieân quan ñeán sub-clause, vieäc thöïc hieän meänh ñeà môùi thaät söï thaát baïi, tuy nhieân ôû ñaây heä thoáng tìm thaáy moät meänh ñeà khaùc lieân quan ñeán khaùi nieäm naøy laø nguoi("Xeda"). Vieäc hôïp nhaát giöõa X vaø "Xeda" laïi ñöôïc thöïc hieän, X seõ coù giaù trò laø Xeda vaø sau ñoù, khi laïi tieáp tuïc thöïc hieän sub-clause vua(X) thì chuùng ta seõ deã daøng thaáy raèng sub-clause laàn naøy ñöôïc thöïc hieän thaønh coâng. Prolog ñaõ tìm ra lôøi giaûi, tuy nhieân, ôû tröôøng hôïp naøy, ngoaøi söï hôïp nhaát, Prolog coøn söû duïng theâm moät "vuõ khí" môùi, ñoù laø söï quay lui.. Khoáng cheá soá löôïng lôøi giaûi Chuùng ta xeùt ví duï sau VD10: predicates nguoi(symbol) chet(symbol) clauses nguoi("Socrates").

nguoi("Xeda"). chet(X) :- nguoi(X).

Ví duï khoâng coù gì phöùc taïp, so vôùi VD6, chuùng ta chæ theâm moät ngöôøi môùi laø Xeda. Khi söû duïng goal ngoaïi, vôùi caâu hoûi nguoi(X) Chuùng ta coù hai lôøi giaûi: X = Socrates X = Xeda.

22

Chuùng ta caûm thaáy hai ñaùp soá naøy laø hieån nhieân. Tuy nhieân neáu chuùng ta duøng goal noäi töông töï VD8, chuùng ta chæ coù moät ñaùp soá laø Socrates. Ñaây laø moät trong nhöõng ñieåm khaùc bieät caên baûn cuûa goal noäi vaø goal ngoaïi. Goal noäi chæ tìm caâu traû lôøi ñaàu tieân coøn goal ngoaïi tìm taát caû caùc caâu traû lôøi coù theå. Ñeå khoáng cheá soá löôïng lôøi giaûi theo yù mình, chuùng ta söû duïng hai vò töø ñaëc bieät laø nhaùt caét (cut) vaø fail, nhö caùc ví duï sau: VD11: Vieát laïi VD10, söû duïng vò töø fail ñeå in ra taát caû caùc lôøi giaûi trong tröôøng hôïp duøng goal noäi. Chöông trình seõ ñöôïc vieát laïi nhö sau: predicates nguoi(symbol) chet(symbol) clauses nguoi("Socrates").

nguoi("Xeda"). chet(X) :- nguoi(X).

goal nguoi(X),nl,write(X),fail nl laø vò töø ñaëc bieät, luoân traû veà keát quaû laø ñuùng, vaø chæ ñôn giaûn laø xuoáng doøng tröôùc khi in thoâng tin môùi ra cöûa soå giao tieáp. Vò töø fail laø moät vò töø ñaëc bieät, luoân luoân traû veà keát quaû laø sai. Nhö vaäy ñeå in ra taát caû caùc keát quaû, chuùng ta duøng moät thuû thuaät (trick) thöôøng gaëp khi laäp trình treân Prolog: sau khi ñaõ tìm thaáy lôøi giaûi cho sub-goal nguoi(X) vaø in giaù trò naøy ra baèng lôøi goïi vò töø write(X), chuùng ta goïi vò töø fail ñeå nhaän ñöôïc keát quaû laø sai. Do cô cheá back-tracing ñaõ noùi ôû treân, Prolog laïi quay laïi thôøi ñieåm goïi sub-goal nguoi(X) ñeå tìm lôøi giaûi khaùc vaø in ra. Quaù trình naøy cöù tieáp tuïc cho ñeán khi khoâng theå tìm thaáy theâm moät lôøi giaûi naøo khaùc. Baèng caùch naøy, chuùng ta ñaõ in ra taát caû caùc lôøi giaûi cho caâu hoûi nguoi(X), tuy nhieân löu yù raèng vôùi goal chính thì khoâng tìm ra lôøi giaûi (do chuùng ta luoân goïi vò töø fail cho sub-goal cuoái cuøng) VD12: Vieát laïi VD10, duøng vò töø nhaùt caét ñeå ñeå in ra moät lôøi giaûi cho caâu hoûi chet(X) cho tröôøng hôïp duøng goal ngoaïi.

23

Vò töø nhaùt caét ñöôïc vieát laø !, laø vò töø ñaëc bieät, seõ traû lôøi ñuùng khi goal chöa tìm thaáy lôøi giaûi naøo, ngöôïc laïi seõ baùo laø sai. Chöông trình seõ ñöôïc vieát laïi nhö sau: predicates nguoi(symbol) chet(symbol) clauses nguoi("Socrates").

nguoi("Xeda"). chet(X) :- nguoi(X),!.

Khi söû duïng goal ngoaïi laø chet(X), khi traû lôøi sub-clause nguoi(X), heä thoáng tìm ra ñaùp soá laø X = Socrates, vaø vì luùc naøy meänh ñeà ñöôïc so truøng chet(X) chöa coù ñaùp soá naøo, vò töø ! tieáp theo seõ traû lôøi laø thaønh coâng. Do chuùng ta ñang söû duïng goal ngoaïi, Prolog seõ tìm taát caû caùc caâu traû lôøi coù theå coù, neân heä thoáng seõ tìm moät caâu traû lôøi khaùc. Ñeå laøm ñieàu ñoù, heä thoáng seõ tìm xem sub-clause nguoi(X) coù ñaùp soá naøo khaùc khoâng. Chuùng ta seõ deã daøng nhaän thaáy raèng heä thoáng tìm thaáy moät ñaùp soá khaùc laø X = Xeda. Tuy nhieân do goal ñaõ coù moät lôøi giaûi, neân sub-clause tieáp theo laø ! seõ baùo laø thaát baïi, vaø lôøi giaûi thöù hai khoâng ñöôïc chaáp nhaän. Toùm taét . Goal noäi seõ tìm lôøi giaûi ñaàu tieân, vaø goal ngoaïi seõ tìm taát caû caùc lôøi giaûi coù theå coù. . Prolog seõ söû duïng cô cheá quay lui khi moät bieán khi chuyeån töø traïng thaùi unbound sang bound seõ daån ñeán söï thaát baïi trong vieäc truy tìm lôøi giaûi . Vò töø fail luoân traû lôøi laø sai, söû duïng khi chuùng ta muoán in taát caû caùc lôøi giaûi vôùi goal noäi. . Vò töø ! seõ traû lôøi ñuùng khi goal chöa coù lôøi giaûi vaø ngöôïc laïi.

24

VI. Laäp trình ñeä quy vôùi Prolog Chuùng ta nhôù laïi raèng vôùi VD2, chuùng ta ñaõ coá gaéng neù traùnh caùch ñaët vaán ñeà ñeå giaûi baøi toaùn giai thöøa theo caùch nhaân doàn caùc soá töø 1 ñeán soá caàn tính giaù trò giai thöøa. Ñieàu naøy seõ daån ñeán moät ñieåm yeáu cuûa Prolog: khoâng cung caáp caùc caáu truùc ñieàu khieån caàn thieát, daån ñeán vieäc khoù khaên khi thöïc hieän pheùp laëp. Tuy nhieân ví duï naøy cuõng cho thaáy moät kyõ thuaät laäp trình taïo neân söùc maïnh chuû yeáu cuûa Prolog: laäp trình ñeä quy. Kyõ thuaät naøy cuõng phuø hôïp vôùi suy nghó cuûa con ngöôøi khi tieáp caän giaûi quyeát vaán ñeà vaø khieán cho vieäc laäp trình treân Prolog coù moät söï uyeån chuyeån vaø nheï nhaøng trong vieäc vieát maõ. Tuy vaäy, noù taïo ra moät söï khoù khaên vôùi nhöõng ngöôøi quen laäp trình thuû tuïc. Chuùng ta seõ xem xeùt laïi töøng böôùc trong vieäc goïi ñeä quy ñeå tìm ra lôøi giaûi. VD13: Xeùt töøng böôùc quaù trình goïi ñeä quy vaø hôïp nhaát cuûa VD7 vôùi goal laø giaithua(2,X) Nhaéc laïi, chuùng ta ñaõ coù ñoaïn chöông trình nhö sau: predicates giaithua(integer,integer) clauses giaithua(0,1):-!. giaithua(X,Y):- X1 = X -1, giaithua(X1,Y1), Y = X*Y1. ÔÛ ñaây coù moät söï thay ñoåi nhoû: chuùng ta ñaët nhaùt caét ñeå chuyeån söï kieän ñaàu thaønh luaät. Chuùng ta muoán khaúng ñònh: neáu soá caàn tìm giai thöøa laø 0 thì giai thöøa cuûa noù laø 1, vaø keát quaû naøy laø duy nhaát, khoâng caàn phaûi tieáp tuïc tìm caùc tröôøng hôïp khaùc. Vôùi goal laø giaithua(2,X), heä thoáng seõ so truøng vôùi meänh ñeà giaithua(0,1) laø meänh ñeà ñaàu tieân tìm thaáy coù lieân quan ñeán khaùi nieäm giaithua. Heä thoáng seõ hôïp nhaát caùc thoâng soá theo thöù töï, 2 hôïp nhaát vôùi 0 vaø X hôïp nhaát vôùi 1. Coâng vieäc hôïp nhaát X vôùi 1 thaønh coâng, X coù giaù trò laø 1, nhöng 2 hôïp nhaát vôùi 0 thaát baïi. Heä thoáng seõ tieáp tuïc tìm kieám lôøi giaûi khaùc baèng caùch so truøng vôùi meänh ñeà khaùc. Laàn naøy heä thoáng so truøng goal vôùi meänh ñeà giaithua(X,Y). Khi taïo moái lieân quan giöõa caùc thoâng soá, heä thoáng hôïp nhaát 2 vôùi X cuûa meänh ñeà vaø Y vôùi X cuûa goal. Chuùng ta seõ

25

kyù hieäu XG laø X thoâng soá cuûa goal. Do Y vaø XG ñeàu chöa coù giaù trò, Prolog seõ xem hai bieán naøy laø moät. Sau ñoù heä thoáng baét ñaàu thöïc hieän töøng sub-clause: . X1 = X - 2 X1 laø bieán môùi, vaø chöa coù giaù trò. X ñaõ coù giaù trò laø 2, neân X - 1 coù giaù trò laø 1. Hôïp nhaát X1 vôùi 1 ta seõ coù giaù trò cuûa X1 laø 1. . giaithua(X1,Y1) ÔÛ ñaây meänh ñeà giai thöøa ñöôïc goïi ñeä quy. Löu yù luùc naøy X1 ñaõ coù giaù trò laø 1, Y1 laø bieán môùi chöa coù giaù trò, vì vaäy nhieäm vuï cuûa heä thoáng laø tìm giaù trò cuûa Y1 sao cho sub-clause giaithua(X1,Y1) cho giaù trò laø ñuùng. Vaø cuõng nhö caùc ví duï treân, caùch thöùc Prolog traû lôøi moät sub-clause cuõng töông töï nhö khi traû lôøi caâu hoûi töø goal, töùc laø laïi so truøng caâu hoûi vôùi caùc meänh ñeà ñaõ bieát

+ So truøng vôùi giaithua(0,1), Prolog tieán haønh hôïp nhaát X1 vôùi 0, Y1 vôùi 1, do X1 ñaõ coù giaù trò laø 1, vieäc hôïp nhaát vôùi 0 thaát baïi, Prolog phaûi so truøng vôùi meänh ñeà khaùc. + So truøng vôùi giaithua(X,Y), Prolog tieán haønh hôïp nhaát X1 vôùi X ñoàng nhaát Y1 vôùi Y. Chuùng ta kyù hieäu X vaø Y ôû laàn goïi ñeä quy naøy laø X2 vaø Y2, vaø söû duïng caùch kyù hieäu töông töï nhö vaäy cho caùc bieán coøn laïi ôû laàn goïi ñeä quy naøy cuõng nhö caùc laàn goïi ñeä quy tieáp theo. Nhö vaäy X2 seõ coù giaù trò laø 1 vaø Y1 seõ coù giaù trò maø Y2 seõ coù.

Töông töï ôû laàn goïi thöù nhaát, caùc sub-clause cuûa meänh ñeà treân ôû laàn goïi thöù hai naøy seõ laàn löôït ñöôïc goïi:

- X12 = X2 - 1, hôïp nhaát X12 vôùi X2 -1, ta coù X12 coù giaù trò laø 0.

- giaithua(X12,Y12), X12 ñaõ coù giaù trò laø 0, Prolog seõ tìm giaù trò cuûa Y12 baèng vieäc tieáp tuïc so truøng giaithua(X12,Y12) vôùi caùc meänh ñeà coù lieân quan:

. So truøng giaithua(X12,Y12) vôùi giaithua(0,1). Do X12 ñaõ coù giaù trò laø 0, Prolog tieán haønh hôïp nhaát X12 vôùi 0 vaø Y12 vôùi 1. Thöïc hieän tieáp sub-clause !, do caâu hoûi giaithua(X12,Y12) chöa tìm ñöôïc caâu traû lôøi naøo, neân sub-clause naøy traû lôøi laø ñuùng. Vieäc

26

thöïc hieän meänh ñeà giaithua(0,1) thaønh coâng, vaø Y12 ñaõ coù giaù trò laø 1 neân caâu hoûi giaithua(X12,Y12) ñaõ coù ñaùp soá. Vò töø ! seõ ngaên chaën vieäc tìm caùc ñaùp soá khaùc, vì vaäy trong tröôøng hôïp naøy, Prolog khoâng tieáp tuïc so truøng tieáp vôùi meänh ñeà giaithua(X,Y).

- Y2 = X2 * Y12, luùc naøy Y2 chöa coù giaù trò, X2 vaø Y12 ñaõ coù giaù trò laø 1 vaø 1 neân Prolog seõ hôïp nhaát Y2 vaø 1. Keát quaû seõ laø Y2 coù giaù trò laø 1.

Nhö vaäy ñeán ñaây caùc sub-clause cuûa meänh ñeà giaithua(X2,Y2) ñaõ thöïc thi thaønh coâng, vaø Y2 ñaõ coù giaù trò laø 1, vaø vì Y1 ñöôïc ñoàng nhaát vôùi Y2, neân Y1 cuõng seõ coù giaù trò la ø1 . Y = X* Y1, luùc naøy Y chöa coù giaù trò, X vaø Y1 ñaõ laàn löôït coù giaù trò laø 2 vaø 1, neân Prolog hôïp nhaát Y vaø 2*1, keát quaû Y seõ coù giaù trò laø 2. Nhö vaäy ñeán ñaây caùc sub-clause cuûa meänh ñeà giaithua(X,Y) ñaõ thöïc thi thaønh coâng, vaø Y ñaõ coù giaù trò laø 2, vaø vì XG ñöôïc ñoàng nhaát vôùi Y, neân XG cuõng seõ coù giaù trò la ø2, vaø lôøi giaûi cuûa baøi toaùn ñaõ ñöôïc tìm thaáy. Toùm taét: . Ñeä quy laø söùc maïnh laäp trình chuû yeáu treân Prolog . Moãi laàn goïi ñeä quy, caùc thoâng soá vaø bieán cuïc boä trong moãi meänh ñeà seõ ñöôïc taïo môùi töông öùng vôùi laàn goïi ñeä quy doù. . Coù theå duøng nhaùt caét ñeå ngaên chaën caùc laàn goïi ñeä quy thöøa khi ñaõ tìm ra ñaùp soá

27

VII. Danh saùch treân Prolog Danh saùch laø kieåu döõ lieäu caáu truùc ñaëc bieät treân Prolog. Coù theå hieåu danh saùch nhö moät kieåu daõy moät chieàu, vaø phaàn töû cuûa danh saùch coù theå thuoäc veà kieåu döõ lieäu baát kyø, tuy nhieân caùc phaàn töû trong cuøng moät danh saùch phaûi cuøng kieåu. Ñònh nghóa kieåu danh saùch Kieåu danh saùch laø moät kieåu döõ lieäu (user-defined type) do ngöôøi duøng ñònh nghóa treân Prolog. Chuùng ta caàn phaûi ñònh nghóa moät kieåu döõ lieäu danh saùch tröôùc khi söû duïng. Phaàn ñònh nghóa kieåu döõ lieäu môùi seõ ñöôïc khai baùo sau töø khoaù domains vaø ñaët ôû ñaàu chöông trình VD14: Khai baùo moät kieåu döõ lieäu môùi laø moät danh saùch soá nguyeân treân Prolog coù teân laø list. domains list = integer* Kyù hieäu * bieåu hieän cho danh saùch. list seõ laø kieåu döõ lieäu danh saùch coù phaàn töû thuoäc kieåu integer. Caáu truùc cuûa danh saùch Moät danh saùch treân Prolog bao goàm hai phaàn: phaàn ñaàu (head) laø phaàn töû ñaàu tieân cuûa danh saùch vaø phaàn ñuoâi (tail) laø danh saùch caùc phaàn töû coøn laïi cuûa danh saùch. Moät danh saùch coù theå moâ taû theo hai caùch: i. Lieät keâ caùc phaàn töû cuûa danh saùch, ví duï: [1,2,3,4,5] ii. Moâ taû phaàn ñaàu vaø phaàn ñuoâi cuûa danh saùch, ngaên caùch bôûi daáu |, ví duï [1|[2,3,4,5]] VD15: Moâ taû moät danh saùch bao goàm 5 soá nguyeân laø 1,2,3,4,5 Danh saùch treân coù theå moâ taû theo caùc caùch sau: [1,2,3,4,5] [1|[2,3,4,5]] [1|[2|[3,4,5]]] [1|[2|[3|[4,5]]]]

28

[1|[2|[3|[4|[5]]]]] [1|[2|[3|[4|[5|[]]]]]] Löu yù: danh saùch roãng coù theå ñöôïc moâ taû nhö sau: [] VD16: Vieát chöông trình in ra phaàn ñaàu vaø phaàn ñuoâi cuûa moät danh saùch. Chöông trình naøy thöïc chaát chæ giuùp chuùng ta nhìn roõ hôn khaùi nieäm veà danh saùch. Chöông trình ñöôïc vieát nhö sau: domains list = integer* predicates indanhsach(list,integer,list) clauses indanhsach(L,H,T):- L = [H|T]. Xeùt khi chuùng ta nhaäp goal vaøo nhö sau: indanhsach([1,2,3,4,5],X,Y) Prolog seõ so truøng goal vôùi meänh ñeà indanhsach(L,H,T), L ñöôïc hôïp nhaát vôùi [1,2,3,4,5], X ñöôïc ñoàng nhaát vôùi H, Y ñöôïc ñoàng nhaát vôùi T. Khi thöïc hieän sub-clause L = [H|T], L ñöôïc hôïp nhaát vôùi [H|T], nhö vaäy phaàn ñaàu cuûa L seõ hôïp nhaát vôùi H, phaàn ñuoâi seõ hôïp nhaát vôùi T. Do L ñaõ coù giaù trò laø [1,2,3,4,5], phaàn ñaàu cuûa L seõ coù giaù trò laø 1, phaàn ñuoâi seõ coù giaù trò laø [2,3,4,5], vaäy sau khi hôïp nhaát, H seõ coù giaù trò laø 1 vaø L seõ coù giaù trò laø [2,3,4,5]. Cuõng töùc laø X seõ coù giaù trò laø 1 vaø Y coù giaù trò laø [2,3,4,5]. Prolog ñaõ tìm thaáy lôøi giaûi vaø seõ in ra lôøi giaûi naøy. Löu yù: i. Chöông trình treân seõ chaïy sai neáu danh saùch nhaäp vaøo laø roãng ([]) do lôøi giaûi cuûa chuùng ta chöa xöû lyù tröôøng hôïp naøy ii. Phaàn meänh ñeà cho vò töø indanhsach coù theå vieát laïi laø indanhsach([H|T],H,T). Toùm taét

29

. Danh saùch laø kieåu döõ lieäu caáu truùc ñaëc bieät do ngöôøi duøng ñònh nghóa treân Prolog

. Moät danh saùch bao goàm hai phaàn: phaàn ñaàu laø phaàn töû ñaàu, phaàn ñuoâi laø danh saùch caùc phaàn töû coøn laïi cuûa danh saùch. . Trong tröôøng hôïp danh saùch roãng, phaàn ñaàu cuûa danh saùch seõ khoâng coù.

30

VIII. Laäp trình ñeä quy vôùi danh saùch treân Prolog Khi xöû lyù danh saùch treân Prolog, ngöôøi laäp trình phaûi töø boû phong caùch duøng voøng laëp ñeå xöû lyù daõy maø phaûi taän duïng kyõ thuaät ñeä quy ñeå tìm ra lôøi giaûi. Chuùng ta xeùt moät soá ví duï sau ñaây: VD17: Vieát vò töø ñeám xem moät danh saùch coù bao nhieâu phaàn töû. Ñaàu tieân chuùng ta phaûi ñònh nghóa ñöôïc coâng vieäc maø chuùng ta ñònh laøm. Chuùng ta seõ vieát moät vò töø nhö sau: dem(list,integer) Chuùng ta ñeám trong moät danh saùch coù bao nhieâu phaàn töû. Ví duï khi goïi goal dem([1,2,3,4],X), ñaùp soá seõ laø X = 4 Tieáp theo chuùng ta phaûi xaùc ñònh moät thuaät giaûi phuø hôïp vôùi tinh thaàn cuûa Prolog. Khoâng theå duøng voøng laëp, chuùng ta phaûi xaây döïng moät giaûi thuaät ñeä quy. Moät giaûi thuaät ñeä quy seõ bao goàm hai phaàn: ñieàu kieän döøng vaø lôøi goïi ñeä quy. Ñieàu kieän döøng cho baøi toaùn naøy raát deã daøng: khi danh saùch khoâng coù phaàn töû naøo, thì hieån nhieân soá phaàn töû cuûa noù laø 0. Vaäy ñieàu kieän döøng seõ ñöôïc vieát nhö sau: dem([],0):-!. Khi tröôøng hôïp danh saùch khoâng coù phaàn töû naøo, ñaùp soá 0 laø duy nhaát, vaäy chuùng ta coù theå duøng nhaùt caét ñeå yeâu caàu Prolog khoâng tìm theâm lôøi giaûi naøo khaùc. Phaàn ñeä quy hôi khoù ñoái vôùi nhöõng ai chöa quen vôùi danh saùch treân Prolog. Prolog chæ cung caáp cho chuùng ta cô cheá chia danh saùch thaønh hai phaàn: phaàn töû ñaàu vaø phaàn ñuoâi danh saùch caùc phaàn töû coøn laïi. Nhö vaäy lôøi giaûi gaàn nhö ñaõ töï noù hieän ra: chuùng ta seõ goïi ñeä quy ñeå ñeám phaàn ñuoâi coù bao nhieâu phaàn töû roài coäng noù vôùi 1 (phaàn töû ñaàu) seõ ra soá phaàn töû trong moät danh saùch. Phaàn naøy seõ ñöôïc vieát nhö sau:

31

dem([H|T],X):- dem(T,X1), X = X1+1. Tö töôûng ñeä quy ñaõ ñöôïc theå hieän raát roõ raøng: ñeám phaàn ñuoâi T cuûa danh saùch ñeå coù ñöôïc toång X1, hôïp nhaát X vôùi X1+1 seõ cho ñaùp soá caàn tìm. Tuy nhieân chuùng ta thaáy ôû ñaây bieán H hoøan toøan khoâng caàn duøng trong veá phaûi cuûa meänh ñeà. Prolog khoâng coi ñaây laø loãi, nhöng seõ "phaøn naøn" veà vieäc naøy. Xeùt veà hieäu quaû laäp trình, hoøan toøan khoâng caàn khai baùo teân bieán môùi cho thaønh phaàn H trong tröôøng hôïp naøy. Coù moät nguyeân taéc ñeå nhaän ra nhöõng bieán "voâ duïng" nhö vaäy: ñoù laø nhöõng bieán chæ xuaát hieän 1 laàn trong suoát meänh ñeà. Ñoái vôùi tröôøng hôïp naøy, ta neân duøng kyù hieäu '_' thay cho teân bieán ñeå bieåu dieãn bieán naøy khoâng caàn duøng trong thuaät giaûi. Vaäy phaàn ñeä quy seõ ñöôïc "tinh cheá" nhö sau: dem([_|T],X):- dem(T,X1), X = X1+1. Nhö vaäy toaøn boä chöông trình hoaøn chænh seõ nhö sau: domains list = integer* predicates dem(list,integer) clauses dem([],0):-!. dem([_|T],X):- dem(T,X1), X = X1+1. VD18: Vieát vò töø tính toång caùc phaàn töû trong moät danh saùch domains list = integer* predicates tong(list,integer) clauses tong([],0):-!. tong([H|T],X):- tong(T,X1), X = X1+H. Tö duy ñeä quy ôû ñaây laø: chuùng ta tính toång phaàn ñuoâi cuûa danh saùch, roài coäng noù vôùi phaàn töû ñaàu ñeå tính toång danh saùch.

32

VD19: Vieát vò töø kieåm tra moät soá nguyeân coù naèm trong danh saùch hay khoâng. Xaùc ñònh vaán ñeà: chuùng ta seõ vieát vò töø ptu(integer,list), khi goïi ptu(2,[1,3,5]) keát quaû seõ laø No, ngöôïc laïi khi goïi ptu(3,[1,3,5]), keát quaû seõ laø Yes. ÔÛ ñaây chuùng ta phaûi xaùc ñònh ñöôïc caùc tröôøng hôïp moät phaàn töû naèm trong moät danh saùch. Vaø chuùng ta phaûi trình baøy ñöôïc caùc khaùi nieäm naøy moät caùch ñeä quy. Sau ñaây laø yù töôûng cuûa thuaät giaûi: coù hai tröôøng hôïp ñeå moät soá nguyeân laø phaàn töû cuûa moät danh saùch: soá nguyeân naøy laø phaàn töû ñaàu cuûa danh saùch hoaëc noù laø phaàn töû cuûa phaàn ñuoâi danh saùch. Sau khi xaùc ñònh ñöôïc yù töôûng, chuùng ta coù baøi giaûi nhö sau: domains list = integer* predicates ptu(integer,list) clauses ptu(H,[H|_]):-!. ptu(H,[_|T]):- ptu(H,T). Löu yù: i./Chuùng ta ñaõ thay theá caùc bieán chæ xuaát hieän moät laàn trong moät meänh ñeà baèng kyù hieäu '_' nhö ñaõ noùi ii./ ÔÛ meänh ñeà ñaàu ñaõ coù kyù hieäu nhaùt caét, neân neáu meänh ñeà naøy ñuùng, baøi toaùn ñaõ coù lôøi giaûi vaø khoâng so truøng ñeán meänh ñeà thöù hai. Nhö vaäy meänh ñeà thöù hai chæ ñöôïc so truøng khi meänh ñeà thöù nhaát thaáy baïi, vaø vì meänh ñeà thöù nhaát öùng vôùi tröôøng hôïp soá nguyeân caàn tìm baèng vôùi phaàn töû ñaàu cuûa danh saùch, neân khi meänh ñeà thöù nhaát thaát baïi, töùc laø soá nguyeân caàn tìm khoâng baèng vôùi phaàn töû ñaàu cuûa danh saùch, neân trong meänh ñeà thöù hai, chuùng ta khoâng caàn quan taâm ñeán phaàn töû ñaàu cuûa danh saùch. VD20: Xaùc ñònh phaàn töû thöù n cuûa danh saùch Khi ta goïi ptn([1,3,5,7,9],2,X) - X = 3 (phaàn töû thöù 2 cuûa danh saùch). Vì Prolog chæ cho chuùng ta truy xuaát phaàn töû ñaàu tieân cuûa danh saùch, neân chuùng ta phaûi xaây döïng thuaät giaûi ñeä quy döïa treân cô sôû naøy: neáu n baèng 1 thì phaàn töû caàn tìm laø phaàn töû ñaàu cuûa danh saùch, ngöôïc laïi thì ñoù seõ laø phaàn töû thöù n -1 cuûa phaàn ñuoâi danh saùch.

33

domains list = integer* predicates ptn(list,integer,integer) clauses ptn([H|_],1,H):-!. ptn([_|T],N,X):- N1 = N - 1, ptn(T,N1,X). VD 21: Taïo ra moät danh saùch bao goàm chæ caùc phaàn töû leû cuûa danh saùch ban ñaàu. Goal khi goïi seõ coù daïng ptle([1,2,3,4,5,6],L) L = [1,3,5] Ñieàu kieän döøng cuûa baøi toaùn raát ñôn giaûn: khi danh saùch laø roãng thì danh saùch ñöôïc taïo ra cuõng laø roãng. Vaø phaàn ñeä quy cuûa baøi toaùn phaûi döïa treân vieäc truy xuaát töø phaàn töû ñaàu tieân cuûa danh saùch vaø goïi ñeä quy cho phaàn ñuoâi. Chuùng ta phaûi xeùt caùc tröôøng hôïp khaùc nhau cuûa phaàn töû ñaàu. domains list = integer* predicates ptle(list,list) clauses ptle([],[]):-!. ptle([H|T],[H|T1]):- H mod 2 = 1, ptle(T,T1),!. ptle([_|T],T1):- ptle(T,T1). ÔÛ ñaây chuùng ta löu yù ñeán meänh ñeà thöù ba: do hai meänh ñeà treân ñeàu coù nhaùt caét, neân meänh ñeà thöù ba chæ ñöôïc so truøng khi hai meänh ñeà treân ñeàu sai. Meänh ñeà thöù hai ñaõ xeùt tröôøng hôïp khi H leû, vì vaäy ôû meänh ñeà thöù ba chaéc chaén H khoâng phaûi laø soá leû, vaø vì vaäy khoâng caàn phaûi xeùt ñeán Toùm taét: . Ñeä quy laø coâng cuï chuû yeáu ñeå xöû lyù danh saùch treân Prolog . Vieäc goïi ñeä quy treân danh saùch thöôøng döïa treân cô sôû chia danh saùch thaønh phaàn ñaàu vaø phaàn ñuoâi. . Söû duïng vò töø nhaùt caét hôïp lyù seõ khieán caùc meänh ñeà trôû neân goïn nheï vaø logic hôn.

34

IX. Danh saùch hai chieàu Danh saùch hai chieàu laø moät tröôøng hôïp ñaëc bieät cuûa danh saùch. Phaàn töû cuûa danh saùch luùc naøy cuõng laø moät danh saùch. Ta xeùt moät ví duï veà khai baùo danh saùch hai chieàu treân Prolog: VD22: Khai baùo danh saùch hai chieàu treân Prolog domains list = integer* list2d = list* Nhö vaäy kieåu döõ lieäu list2d laø kieåu döõ lieäu danh saùch maø phaàn töû cuûa noù thuoäc kieåu list, töùc laø moät danh saùch khaùc. Vieäc laäp trình vôùi danh saùch hai hay nhieàu chieàu, veà cô baûn, hoøan toøan khoâng khaùc vôùi vieäc laäp trình danh saùch moät chieàu, töùc cuõng söû duïng caùc giaûi thuaät xöû lyù danh saùch bình thöôøng. Tuy nhieân chuùng ta caàn chuù yù raèng phaàn töû cuûa danh saùch naøy cuõng laø moät danh saùch. VD23: Vieát chöông trình ñeám treân moät danh saùch hai chieàu cuûa caùc soá nguyeân L coù bao nhieâu phaàn töû con coù toång caùc phaàn töû laø soá chaún. Vôùi baøi toaùn naøy, chuùng ta phaûi vieát theâm moät vò töø phuï ñeå coù ñöôïc lôøi giaûi domains

list = integer* list2d = list*

predicates tong(list,integer) dem(list2d,integer) clauses tong([],0):-!. tong([H|T],X):-tong(T,X1), X = H+X1. dem([],0):-!. dem([H|T],X):-tong(H,N), N mod 2 = 0, dem(T,X1), X = X1 + 1,!. dem([_|T],X):- dem(T1,X).

35

Toùm taét . Danh saùch nhieàu chieàu laø moät danh saùch trong ñoù caùc phaàn töû cuõng laø danh saùch . Veà maët tö duy, laäp trình ñeå xöû lyù treân danh saùch nhieàu chieàu khoâng khaùc nhieàu vôùi xöû lyù danh saùch moät chieàu . Caùc phaàn töû cuûa danh saùch nhieàu chieàu cuõng laø danh saùch, neân coù theå aùp duïng caùc giaûi thuaät xöû lyù danh saùch ñeå xöû lyù caùc phaàn töû naøy.