30
Hướng dẫn SWI-Prolog Lập trình Logic Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 1 HƯỚNG DẪN SWI-PROLOG (Version 5.6.64) 1. Bài hướng dẫn 1: Cài ñặt SWI-Prolog Bước 1 . Vào trang Web của SWI-Prolog: http://www.swi-prolog.org/ . Tải file cài ñặt SWI-Prolog cho Windows (version 5.6.64): http://www.swi- prolog.org/download/stable/bin/w32pl5664.exe , dung lượng khoảng 6.79 MB. Lưu ý là tải ñúng bản cài ñặt cho Windows vì SWI-Prolog còn nhiều bản cài ñặt cho các platform khác nữa. Bước 2 . Chạy file cài ñặt w32pl5664.exe ñể bắt ñầu cài ñặt SWI-Prolog cho Windows. Bước 3 . Nhấn I Agree, sau ñó nhấn Next trong hộp thoại kế. Dung lượng ñĩa trống yêu cầu khoảng 23.3 MB.

Huong Dan SWI-Prolog

Embed Size (px)

Citation preview

Page 1: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 1

HƯỚNG DẪN SWI-PROLOG (Version 5.6.64)

1. Bài hướng dẫn 1: Cài ñặt SWI-Prolog

Bước 1. Vào trang Web của SWI-Prolog: http://www.swi-prolog.org/. Tải file cài

ñặt SWI-Prolog cho Windows (version 5.6.64): http://www.swi-

prolog.org/download/stable/bin/w32pl5664.exe, dung lượng khoảng 6.79 MB.

Lưu ý là tải ñúng bản cài ñặt cho Windows vì SWI-Prolog còn nhiều bản cài ñặt

cho các platform khác nữa.

Bước 2. Chạy file cài ñặt w32pl5664.exe ñể bắt ñầu cài ñặt SWI-Prolog cho

Windows.

Bước 3. Nhấn I Agree, sau ñó nhấn Next trong hộp thoại kế. Dung lượng ñĩa trống

yêu cầu khoảng 23.3 MB.

Page 2: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 2

Bước 4. Trong hộp thoại chọn thư mục cài ñặt ta chọn C:\Program Files\SWI-

Prolog (thay vì mặc ñịnh là C:\Program Files\pl), ñơn giản vì một tên ñầy ñủ thì

tốt hơn.

Bước 5. Nhấn Next. Trong hộp thoại này ta chọn ñuôi cho file nguồn Prolog (là pl

hay pro). Ta chọn pl nếu như không có file type nào ñăng kí ñuôi này (file nguồn

của Perl cũng dùng ñuôi pl), nếu không thì chọn pro. Ở ñây chọn pl.

Page 3: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 3

Bước 6. Nhấn Install và ñợi SWI-Prolog cài ñặt xong.

ðể thuận tiện, chúng ta gọi {SWI-Prolog} là thư mục cài ñặt SWI-Prolog (là thư

mục ñã chọn ở Bước 4). Sau khi cài ñặt thì thư mục này chứa toàn bộ chương

trình, dll và các file khác của SWI-Prolog. Sau ñây là một số file và thư mục quan

trọng:

• {SWI-Prolog}\bin: chứa các file thực thi, dll của SWI-Prolog. Trong ñó

file {SWI-Prolog}\bin\plwin.exe là file chương trình thực thi của SWI-

Prolog. File {SWI-Prolog}\bin\plcon.exe là file chương trình chạy trong

Console.

• {SWI-Prolog}\library: chứa các file nguồn của các thư viện SWI-Prolog.

• {SWI-Prolog}\doc: chứa tài liệu hướng dẫn dạng Web. Khi chạy SWI-

Prolog, ta có thể truy nhập Help → Online manual… ñể nhận ñược giúp

ñỡ với nội dung tương tự nhưng trong cửa sổ Help của SWI-Prolog. Ta

cũng có thể download dạng pdf của tài liệu hướng dẫn này trên trang Web

của SWI-Prolog (http://www.swi-prolog.org/download/stable/doc/SWI-

Prolog-5.6.59.pdf).

• {SWI-Prolog}\demo: chứa các file nguồn demo của SWI-Prolog. Trong ñó

có file {SWI-Prolog}\demo\likes.pl là một file nguồn demo.

File nguồn SWI-Prolog có ñuôi pl (như ñã chọn ở Bước 5), chứa khai báo của các

sự kiện cũng như các luật, … cho Knowledge Base (trong Phần hướng dẫn tiếp

chúng ta viết tắt là KB). Các file này ñược gắn với plwin.exe. Khi mở file nguồn

Prolog thì plwin.exe sẽ chạy, SWI-Prolog sẽ ñặt thư mục làm việc là thư mục

chứa file này và nạp các sự kiện, các luật, … trong file này vào KB.

Page 4: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 4

2. Bài hướng dẫn 2: Truy vấn

Chạy chương trình SWI-Prolog (file thực thi plwin.exe) chúng ta có giao diện

chính của SWI-Prolog như hình sau

Sau lời chào mừng và giới thiệu là dấu nhắc ñợi truy vấn. Chúng ta gõ câu truy

vấn vào sau dấu nhắc truy vấn của SWI-Prolog. Dấu nhắc của Prolog có dạng n

?- với n là số thứ tự của câu truy vấn hiện tại. Chúng ta gõ câu truy vấn, rồi ñến

dấu chấm ‘.’ và nhấn Enter ñể thực hiện truy vấn. Nếu câu truy vấn sai cú pháp

hay có lỗi thời gian chạy thì SWI-Prolog sẽ ñưa ra thông báo lỗi. Nếu không,

SWI-Prolog sẽ trả lời truy vấn. Nếu một truy vấn có nhiều lời giải thì bạn gõ ‘;’

ñể xem các lời giải khác. Nếu không thì nhấn Enter ñể kết thúc trả lời truy vấn và

sang câu truy vấn khác.

Chúng ta có thể chia các truy vấn SWI-Prolog ra làm hai loại:

Page 5: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 5

• Loại truy vấn mà chúng ta trông ñợi vào kết quả hợp nhất (hay tìm kiếm lời

giải của) SWI-Prolog. Thường thì truy vấn loại này có chứa các biến và có

thể có nhiều giá trị hợp nhất cho biến.

• Loại truy vấn mà chúng ta trông chờ vào các hiệu ứng lề (side-effect) ñể

SWI-Prolog thực hiện một công việc nào ñó. Thường thì truy vấn loại này

không chứa biến và ta có thể gọi nó là lệnh.

Bước 1. Nhấp ñúp file {SWI-Prolog}\demo\likes.pl ñể chạy SWI-Prolog và nạp

các sự kiện, luật trong file nguồn này vào KB.

Bước 2. Truy vấn listing ñể xem các sự kiện và luật trong KB.

1 ?- listing. italian(pizza). italian(spaghetti). likes(sam, A) :- indian(A), mild(A). likes(sam, A) :- chinese(A). likes(sam, A) :- italian(A). likes(sam, chips). mild(dahl). mild(tandoori). mild(kurma). chinese(chow_mein). chinese(chop_suey). chinese(sweet_and_sour). indian(curry). indian(dahl). indian(tandoori).

Page 6: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 6

indian(kurma). true.

Bước 3. Truy vấn mild(dahl).

2 ?- mild(dahl). true.

Bước 4. Truy vấn mild(curry).

3 ?- mild(curry). false.

Bước 5. Truy vấn indian(X).

4 ?- indian(X). X = curry

Bước 6. Gõ ‘;’ ñể xem lời giải khác.

4 ?- indian(X). X = curry ; X = dahl

Bước 7. Gõ Enter ñể dừng truy vấn hiện tại.

4 ?- indian(X). X = curry ; X = dahl .

Bước 8. Truy vấn likes(sam, X). Và dùng ‘;’ ñể xem tất cả các lời giải.

5 ?- likes(sam, X). X = dahl ; X = tandoori ; X = kurma ; X = chow_mein ; X = chop_suey ; X = sweet_and_sour ;

Page 7: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 7

X = pizza ; X = spaghetti ; X = chips. 6 ?-

Bước 9. Truy vấn !!. ñể gọi lại truy vấn trước ñó. Sau ñó nhấn Enter ñể dừng các

hợp nhất khác.

6 ?- !!. likes(sam, X). X = dahl .

Bước 10. Truy vấn h. ñể hiển thị danh sách các truy vấn ñã gọi.

7 ?- h. 1 listing. 2 mild(dahl). 3 mild(curry). 4 indian(X). 5 likes(sam, X). 6 likes(sam, X).

Bước 11. Truy vấn !2. ñể gọi lại truy vấn thứ 2.

7 ?- !2. mild(dahl). true.

Page 8: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 8

3. Bài hướng dẫn 3: Thao tác file nguồn SWI-Prolog

Bước 1. Chạy chương trình SWI-Prolog từ file plwin.exe (ñể không có file nguồn

nào ñược nạp vào KB). Nhấp lệnh ñơn File → New… ñể soạn một file nguồn mới.

Trong hộp thoại Create new Prolog source ñặt tên file là hello.pl, SWI-Prolog sẽ

triệu gọi Editor của mình (gọi là PceEmacs) ñể bạn soạn file nguồn hello.pl.

Bước 2. Gõ vào luật duy nhất sau ñây trong file hello.pl

hello :- write('Hello World').

Sau ñó lưu file và ñóng Editor.

Bước 3. Nhấp lệnh ñơn File → Consult… ñể nạp một file nguồn. Trong hộp thoại

Load file into Prolog chọn nạp file hello.pl. SWI-Prolog sẽ nạp các sự kiện và

luật trong file này vào KB.

Bước 4. Truy vấn listing ñể thấy rằng luật trong file hello.pl ñã ñược thêm vào

KB.

1 ?- listing. % Foreign: tcp_debug/1 hello :- write('Hello World'). true.

Bước 5. Truy vấn hello ñể thấy công việc của vị từ hello/0. Vị từ này in ra dòng

chữ Hello World.

2 ?- hello. Hello World true.

Page 9: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 9

Bước 6. Nhấp lệnh ñơn File → Edit… ñể sửa một file nguồn. Trong hộp thoại Edit

existing file chọn file hello.pl ñể sửa file này. Trong Editor sửa nội dung file này

thành như sau

hello(X) :- write('Hello '), write(X).

Sau ñó lưu lại và ñóng Editor.

Bước 7. Nhấp lệnh ñơn File → Reload modified files ñể nạp lại file nguồn vì

SWI-Prolog không tự nạp lại. Truy vấn listing ñể thấy những thay ñổi này.

3 ?- listing. hello(A) :- write('Hello '), write(A). true.

Bước 8. Truy vấn hello(nam) ñể thấy công việc của vị từ hello/1. Vị từ này in

ra dòng chữ Hello rồi ñến ñối số ta gởi vào.

4 ?- hello(nam). Hello nam true.

Bước 9. Nhấp lệnh ñơn File → Navigator… ñể mở cửa sổ Prolog Navigator. Tìm

ñến nút của file nguồn hello.pl (file phải ñể trong ổ ñĩa cài ñặt SWI-Prolog, có thể

dùng nút mũi tên lên bên trái của thanh toolbar ñể duyệt thư mục). Ta thấy trong

nút này chứa nút hello/1 cho luật của chúng ta, chúng ta cũng thấy rằng nút này có

nút con write/1 ñể chỉ hello/1 phụ thuộc vào write/1.

Page 10: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 10

Lưu ý:

- Khi nạp file nguồn bằng lệnh ñơn File → Consult… thì SWI-Prolog sẽ

thêm các luật và sự kiện của file mới vào KB hiện tại chứ không xóa nội

dung của KB và SWI-Prolog sẽ thêm file này vào danh sách các file mà nó

ñã nạp. Do ñó khi nhấp lệnh ñơn File → Reload modified files thì toàn bộ

các file này sẽ ñược nạp lại vào KB. Nếu ñang có cửa sổ SWI-Prolog mà

mở thêm file nguồn mới bằng cách nhấp ñúp thì SWI-Prolog sẽ mở file này

trong một tiến trình khác (cửa sổ khác) và duy trì các KB riêng lẻ trong

từng tiến trình.

- Có các vị từ trong SWI-Prolog làm các công việc tương ñương với các lệnh

trong trình ñơn File. Các bạn xem trong tài liệu tham khảo của SWI-Prolog

ñể biết cặn kẽ vì ñây là các vị từ rất hay dùng và sẽ ñược dùng trong các

Bài hướng dẫn dưới.

+ make/0 ñể nạp lại các file ñã nạp.

Page 11: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 11

+ edit/0, edit/1 ñể sửa file nguồn.

+ edit(file(File)) ñể tạo mới file nguồn.

+ consult/1 hay dạng viết gọn [File] ñể nạp một file nguồn.

- Lệnh ñơn Edit → Copy và Edit → Paste dùng ñể copy hay dán nội dung

(bôi xanh) vào hay từ Clipboard. Chú ý là phím tắt Ctrl + V làm việc tốt

nhưng Ctrl + C không ñược dùng cho Copy (Ctrl + C là phím tắt của lệnh

ñơn Run → Interrupt dùng ñể ngắt lệnh ñang chạy).

Page 12: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 12

4. Bài hướng dẫn 4: Run và Debug

Bước 1. Chạy chương trình SWI-Prolog từ file thực thi plwin.exe (ñể không có

file nguồn nào ñược nạp vào KB). Nhấp lệnh ñơn File → New… ñể soạn một file

nguồn mới. ðặt tên file là descendant.pl với nội dung sau

child(martha,charlotte).

child(charlotte,caroline).

child(caroline,laura).

child(laura,rose).

descend(X,Y) :- child(X,Y).

descend(X,Y) :- child(X,Z), descend(Z,Y).

Bước 2. Truy vấn consult(descendant) ñể nạp file này vào KB.

1 ?- consult(descendant). % descendant compiled 0.00 sec, 984 bytes true.

Bước 3. Truy vấn trace ñể theo vết quá trình tìm kiếm lời giải của câu truy vấn

kế.

2 ?- trace. Unknown message: query(yes) [trace] 2 ?-

Bước 4. Truy vấn descend(martha, X).

2 ?- trace. Unknown message: query(yes) [trace] 2 ?- descend(martha, X). Call: (7) descend(martha, _G476) ?

Page 13: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 13

Bước 5. Nhấn Enter ở các dấu nhắc tiếp theo ñể SWI-Prolog tiếp tục quá trình theo

vết, cho ñến khi một lời giải ñược ñưa ra.

2 ?- trace. Unknown message: query(yes) [trace] 2 ?- descend(martha, X). Call: (7) descend(martha, _G476) ? creep Call: (8) child(martha, _G476) ? creep Exit: (8) child(martha, charlotte) ? creep Exit: (7) descend(martha, charlotte) ? creep X = charlotte

Bước 6. Tới ñây chúng ta nhấn Enter ñể kết thúc truy vấn hoặc nhấn ‘;’ ñể SWI-

Prolog tiếp tục theo vết các lời giải khác. Nhấn ‘;’ và sau ñó là Enter cho ñến khi

thấy lời giải thứ hai thì nhấn Enter ñể kết thúc truy vấn.

2 ?- trace. Unknown message: query(yes) [trace] 2 ?- descend(martha, X). Call: (7) descend(martha, _G476) ? creep Call: (8) child(martha, _G476) ? creep Exit: (8) child(martha, charlotte) ? creep Exit: (7) descend(martha, charlotte) ? creep X = charlotte ; Redo: (7) descend(martha, _G476) ? creep Call: (8) child(martha, _L174) ? creep Exit: (8) child(martha, charlotte) ? creep Call: (8) descend(charlotte, _G476) ? creep Call: (9) child(charlotte, _G476) ? creep Exit: (9) child(charlotte, caroline) ? creep Exit: (8) descend(charlotte, caroline) ? creep Exit: (7) descend(martha, caroline) ? creep X = caroline . [debug] 3 ?-

Bước 7. Kí hiệu [debug] trước dấu nhắc truy vấn cho biết SWI-Prolog ñang trong

chế ñộ debug. Ở chế ñộ debug, SWI-Prolog sẽ dừng ở các spy-point, break-point

Page 14: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 14

hay trace-point và bơm thông tin vào các cổng, giúp ích cho quá trình debug.

Chúng ta ñặt một ñiểm spy bằng cách dùng vị từ spy/1. Truy vấn spy(child)

ñể ñặt ñiểm spy ở vị từ child.

[debug] 3 ?- spy(child). % Spy point on child/2 true.

Bước 8. Bây giờ truy vấn descend(X, caroline) ñể thấy tác dụng của vị từ

spy/1. Nhấn Enter liên tiếp ñến khi xong truy vấn này.

[debug] 4 ?- descend(X, caroline). Call: (8) child(_G487, caroline) ? creep Exit: (8) child(charlotte, caroline) ? creep Exit: (7) descend(charlotte, caroline) ? creep X = charlotte .

Bước 9. Như vậy ta thấy SWI-Prolog dừng ở các vị từ child. Với vị từ trace/0

SWI-Prolog theo vết tất cả các vị từ dùng trong quá trình hợp nhất goal tiếp sau

trace và chỉ goal này mà thôi. Với spy/1, chúng ta ñặt các ñiểm spy trên các vị từ

và SWI-Prolog sẽ luôn dừng ở các vị từ này khi ñối sánh mọi goal sau ñó. ðương

nhiên SWI-Prolog chỉ dừng khi ñang trong chế ñộ debug. ðể kiểm tra, ta thoát

khỏi chế ñộ debug bằng vị từ nodebug/0.

[debug] 5 ?- nodebug. true. 6 ?-

Bước 10. Truy vấn descend(X, Y) ñể thấy rằng SWI-Prolog không dừng ở

các ñiểm spy khi không ở chế ñộ debug. Nhấn ‘;’ ñể xem tất cả các hợp nhất.

6 ?- descend(X, Y). X = martha, Y = charlotte ;

Page 15: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 15

X = charlotte, Y = caroline ; X = caroline, Y = laura ; X = laura, Y = rose ; X = martha, Y = caroline ; X = martha, Y = laura ; X = martha, Y = rose ; X = charlotte, Y = laura ; X = charlotte, Y = rose ; X = caroline, Y = rose ; false.

Bước 11. Truy vấn gtrace ñể vào chế ñộ debug nhưng dùng giao diện ñồ họa

thay vì các dòng thông tin dạng text. Chúng ta cũng có thể dùng lệnh ñơn Debug

→ Graphical debugger với cùng công dụng.

7 ?- gtrace. % The graphical front-end will be used for subsequent tracing true. [debug] 8 ?-

Bước 12. Bây giờ gõ truy vấn descend(X, Y). SWI-Prolog sẽ hiện công cụ

thực hiện debug trên giao diện ñồ họa.

Page 16: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 16

Bước 13. Các bạn nên tự nghiên cứu nhiều về debugger này vì nó là một công cụ

rất mạnh và rất có ích. Bây giờ chúng ta cứ việc nhấn nút có hình mũi tên xuống

(Show unification) cho ñến khi thấy SWI-Prolog ñưa ra một lời giải. Nhấp chuột

vào cửa sổ chính và nhấn ‘;’ ñể SWI-Prolog tìm lời giải kế tiếp và do ñó nó lại

triệu gọi debugger này với thông tin ñối sánh mới.

Page 17: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 17

Bước 14. Tiếp tục nhấn nút có hình mũi tên xuống (Show unification) cho ñến khi

SWI-Prolog ñưa ra lời giải thứ hai. Nhấp chuột vào cửa sổ chính và nhấn Enter ñể

kết thúc truy vấn.

[debug] 8 ?- descend(X, Y). X = martha, Y = charlotte ; X = charlotte, Y = caroline . [debug] 9 ?-

Bước 15. Chúng ta xóa các ñiểm spy trên vị từ child bằng nospy(child). Hay

ñơn giản dùng nospyall/0 ñể xóa tất cả các ñiểm spy.

[debug] 9 ?- nospyall.

Page 18: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 18

% Spy point removed from child/2 true.

Bước 16. Chúng ta thực hiện truy vấn descend(X, Y) và thấy rằng không có

thông tin debug nào ñược in ra cũng như debugger ñồ họa không ñược triệu gọi

nữa.

[debug] 10 ?- descend(X, Y). X = martha, Y = charlotte ; X = charlotte, Y = caroline . [debug] 11 ?-

Bây giờ chúng ta sẽ cùng tìm hiểu hai lệnh có ích khác trong trình ñơn Run là

Interrupt và New thread.

Bước 1. Chạy chương trình SWI-Prolog từ file thực thi plwin.exe (ñể không có

file nguồn nào ñược nạp vào KB). Truy vấn edit(file(‘loop.pl’)) ñể tạo

mới file nguồn loop.pl.

1 ?- edit(file('loop.pl')). true.

Bước 2. Trong Editor, gõ nội dung của file nguồn loop.pl như sau:

p(X) :- q(X).

q(X) :- p(X).

Bước 3. Truy vấn [loop] ñể nạp file nguồn loop.pl vào KB.

2 ?- [loop]. % loop compiled 0.00 sec, 684 bytes true.

Bước 4. Truy vấn p(X).

Page 19: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 19

3 ?- p(X).

Bước 5. Vì ñịnh nghĩa vòng của vị từ p/1 nên SWI-Prolog sẽ rơi vào vòng lặp

không kết thúc khi ñi tìm lời giải cho truy vấn trên. ðể ngắt quá trình tìm lời giải

cho truy vấn trên, chúng ta chọn lệnh ñơn Run → Interrupt.

3 ?- p(X). Action (h for help) ?

Bước 6. Chúng ta có một số tùy chọn lệnh khác nhau ñể ngắt chương trình. Nhấn

h ñể thấy các tùy chọn lệnh này.

3 ?- p(X). Action (h for help) ? Options: a: abort b: break c: continue e: exit g: goals t: trace h (?): help Action (h for help) ?

Bước 7. Nhập lệnh t (trace) ñể theo vết quá trình tìm lời giải cho truy vấn của

SWI-Prolog.

Action (h for help) ? trace continue (trace mode) Call: (3,265,194) q(_G548) ? creep Call: (3,265,195) p(_G548) ? creep Call: (3,265,196) q(_G548) ? creep Call: (3,265,197) p(_G548) ? creep Call: (3,265,198) q(_G548) ? creep Call: (3,265,199) p(_G548) ? creep Call: (3,265,200) q(_G548) ? creep Call: (3,265,201) p(_G548) ? creep Call: (3,265,202) q(_G548) ?

Page 20: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 20

Bước 8. Ta thấy vị từ q/1 và p/1 cứ thay phiên nhau ñược gọi. Ta có nhấn Enter

hoài thì dãy lời gọi trên cũng không kết thúc. Ta nhập lệnh a (abort) ñể ngắt bỏ

truy vấn.

Action (h for help) ? trace continue (trace mode) Call: (3,265,194) q(_G548) ? creep Call: (3,265,195) p(_G548) ? creep Call: (3,265,196) q(_G548) ? creep Call: (3,265,197) p(_G548) ? creep Call: (3,265,198) q(_G548) ? creep Call: (3,265,199) p(_G548) ? creep Call: (3,265,200) q(_G548) ? creep Call: (3,265,201) p(_G548) ? creep Call: (3,265,202) q(_G548) ? abort % Execution Aborted 4 ?-

Bước 9. Truy vấn q(a). Chúng ta biết rằng SWI-Prolog tiếp tục rơi vào vòng lặp

không kết thúc.

4 ?- q(a).

Bước 10. Nhấp lệnh ñơn Run → New thread, SWI-Prolog sẽ hiện một cửa sổ

mới (Thread 2) chạy cùng với cửa sổ chính (Thread main).

Page 21: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 21

Bước 11. Trong cửa sổ thread mới này thực hiện truy vấn listing.

1 ?- listing. % Foreign: tcp_debug/1 p(A) :- q(A). q(A) :- p(A). true.

Bước 12. Ta thấy rằng KB này giống hệt như KB của thread main. Thực chất,

trong trường hợp này chỉ có một KB. Các thread khác nhau sẽ thực hiện các truy

vấn ñộc lập nhưng chia sẻ cùng KB. Như vậy trong khi thread main vẫn ñang còn

bận tìm lời giải thì chúng ta có thể dùng thread 2 cho các công việc khác. ðây là

cách dùng có ích của thread. Lưu ý rằng việc dùng nhiều thread khác với việc

chúng ta mở nhiều chương trình SWI-Prolog khác nhau (bằng file thực thi

plwin.exe hay chạy tự ñộng các file nguồn SWI-Prolog) vì khi này các KB là ñộc

lập cho từng process. Bây giờ truy vấn halt trong thread 2.

Page 22: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 22

2 ?- halt. ERROR: [Thread 2] halt/1: No permission to halt thread `2' (Only from thread `main') 3 ?-

Bước 13. Chúng ta thấy rằng một lỗi thời gian chạy ñược ñưa ra cho truy vấn

halt/0. Lỗi này là do thread 2 không ñủ quyền dùng lệnh halt/0, chỉ có thread

main mới ñủ quyền. Chúng ta nhấp chuột vào cửa sổ của thread main và nhấn Ctrl

+ C (phím tắt của lệnh ñơn File → Interrupt) ñể ngắt chương trình. Nhấn tiếp

lệnh e (exit) ñể thoát SWI-Prolog. SWI-Prolog sẽ ñóng cả cửa sổ thread main lẫn

thread 2.

Page 23: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 23

5. Bài hướng dẫn 5: Setting và Customise

Bước 1. Chạy chương trình SWI-Prolog từ file thực thi plwin.exe. Nhấp lệnh ñơn

Settings → Font… ñể chọn font hiển thị cho cửa sổ chính của SWI-Prolog.

Bước 2. Trong hộp thoại chọn Font, chúng ta chọn font Courier New, style

Regular, size 12. Font Courier New là font chữ có ñộ rộng cố ñịnh, rất thích hợp

cho hiển thị nội dung trong cửa sổ chính của SWI-Prolog. Sau khi chọn font, SWI-

Prolog ngay lập tức hiển thị cửa sổ chính theo font ñã chọn.

Bước 3. Nhấp lệnh ñơn Settings → User init file… ñể tạo một file cấu hình,

customise các tùy chọn SWI-Prolog. Nếu bạn chưa có file này (mặc ñịnh là chưa

có) thì một thông báo ñược ñưa ra

Page 24: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 24

Bước 4. Nhấn OK ñể tạo một file cài ñặt như thế.

Bước 5. Trong cửa sổ editor bạn duyệt ñến phần nói về DEBUGGING.

Bước 6. Theo hướng dẫn của phần này, bạn khử ghi chú cho dòng lệnh

% :- (current_prolog_flag(gui, true) -> guitracer ; true).

Bằng cách xóa dấu % ở ñầu (% là dấu bắt ñầu ghi chú trên một dòng của Prolog).

Editor sẽ tự ñộng tô màu lại ñể bạn biết ñây là một dòng lệnh chứ không phải là

một ghi chú nữa.

Page 25: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 25

Bước 7. Lưu file (Ctrl + S) và ñóng cửa sổ editor này lại.

Bước 8. Truy vấn [descendant] ñể Consult file nguồn descendant.pl ở phần

trước.

1 ?- [descendant]. % descendant compiled 0.00 sec, 1,328 bytes true.

Bước 9. Truy vấn trace ñể vào chế ñộ trace.

2 ?- trace. Unknown message: query(yes) [trace] 2 ?-

Bước 10. Truy vấn descend(X, Y). Chúng ta thấy rằng SWI-Prolog sẽ dùng

cửa sổ ñồ họa ñể chạy chế ñộ trace thay vì cửa sổ chính của SWI-Prolog như

trước.

Page 26: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 26

Bước 11. Truy vấn halt ñể ñóng SWI-Prolog.

3 ?- halt.

Bước 12. Khởi ñộng lại SWI-Prolog từ file thực thi plwin.exe.

Page 27: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 27

Bước 13. Từ những dòng ñầu chúng ta thấy SWI-Prolog tự ñộng nạp file cấu hình

của chúng ta (file pl.ini) cũng như dùng cửa sổ ñồ họa ñể trace. Như vậy file cấu

hình là một file nguồn SWI-Prolog, ñược SWI-Prolog nạp ngay sau khi chạy (nhờ

tên và vị trí lưu trữ ñặc biệt của nó). Do ñó các khai báo, các lệnh, … trong file

này sẽ có tác dụng ngay sau khi SWI-Prolog chạy. Các bạn có toàn quyền thêm

các khai báo, các lệnh, … mới (dĩ nhiên bạn phải biết rõ về nó) hay khử ghi chú

một số khai báo có sẵn trong file mẫu này.

Page 28: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 28

6. Bài hướng dẫn 6: Sử dụng một số vị từ có ích khác

Bước 1. Chạy SWI-Prolog từ file thực thi plwin.exe. Các tham chiếu file tương

ñối (trong edit/1, consult/1, …) ñều lấy thư mục làm việc của SWI-Prolog làm

gốc. Chúng ta dùng truy vấn pwd ñể kiểm tra thư mục này.

1 ?- pwd. c:/program files/swi-prolog/bin true.

Như vậy nếu chạy SWI-Prolog từ file thực thi plwin.exe thì thư mục làm việc là

{SWI-Prolog}\bin như trên cho thấy. Lưu ý là nếu tạo shortcut cho file plwin.exe

và chạy từ shortcut này (chẳng hạn shortcut trên Desktop) thì thư mục làm việc sẽ

khác.

Bước 2. Truy vấn ls ñể xem danh sách file trong thư mục làm việc. Lệnh này có

ích cho consult/1, edit/1, …

2 ?- ls. descendant.pl hello.pl loop.pl true.

Bước 3. ðóng SWI-Prolog và nhấp ñúp file {SWI-Prolog}\demo\likes.pl ñể chạy

SWI-Prolog và nạp file nguồn này.

Bước 4. Truy vấn pwd ñể kiểm tra thư mục làm việc.

1 ?- pwd. c:/program files/swi-prolog/demo true.

Chúng ta thấy rằng thư mục làm việc ñược ñặt thành thư mục chứa file nguồn ñã

khởi ñộng SWI-Prolog.

Page 29: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 29

Bước 5. Truy vấn help/0 ñể hiển thị hộp thoại Help của SWI-Prolog (giống như

dùng lệnh Help → Online manual…). Chúng ta truy vấn help(write) ñể hiển

thị Help về vị từ write.

2 ?- help(write). true.

SWI-Prolog sẽ hiển thị hội thoại Help ngay mục của vị từ write, như hình dưới.

Bước 6. Truy vấn write(‘Hello World’) ñể in chuỗi Hello World.

3 ?- write('Hello World'). Hello World true.

Bước 7. Khác với vị từ write dùng ñể in ra dạng thân thiện của ñối tượng, vị từ

display dùng ñể in ra dạng biểu diễn bên trong. Truy vấn display([1, 2])

ñể thấy biểu diễn bên trong của list [1, 2].

Page 30: Huong Dan SWI-Prolog

Hướng dẫn SWI-Prolog Lập trình Logic

Vũ Quốc Hoàng Tp. HCM, 2/2009 Page 30

4 ?- display([1, 2]). .(1, .(2, [])) true.

Bước 8. Truy vấn display(1 + 2) ñể thấy biểu diễn bên trong của 1 + 2.

5 ?- display(1 + 2). +(1, 2) true.

Bước 9. Vị từ read ñể ñọc giá trị hợp nhất vào một biến. Truy vấn read(X),

display(X). Và gõ vào 1+1, dấu ‘.’ và nhấn Enter.

6 ?- read(X), display(X). |: 1+1. +(1, 1) X = 1+1. 7 ?-