Upload
lqn19832003
View
1.172
Download
14
Embed Size (px)
Citation preview
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.
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.
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.
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:
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).
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 ;
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.
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.
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.
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.
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).
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) ?
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
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 ;
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.
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.
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.
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).
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) ?
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).
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.
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.
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
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.
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.
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.
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.
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.
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].
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 ?-