Tải bản đầy đủ (.ppt) (30 trang)

Lập trình logic và ràng buộc (Logic Programming and Constraint)

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

Lập trình logic và ràng buộc
(Logic Programming and Constraint)

Ts. Lê Mạnh Hải
Khoa CNTT,
ĐH Kỹ thuật Công nghệ TP HCM
1


Bài 2: Kỹ thuật lập trình
• Mục tiêu:






Các kỹ thuật xử lý danh sách
Các phép toán
Xử lý CSDL
Nhập xuất qua tập tin

2


Xử lý danh sách
Danh sách (list) là cấu trúc dữ liệu quan
trọng.
•Biểu diễn danh sách [X], [a,b,c], [], [Head|
Tail].
•Các vị từ build-in (/doc/Manual/lists.html‘)










member(?Elem, ?List), delete(+List1, @Elem, -List2)
append(?List1, ?List2, ?List1AndList2),
select(?Elem, ?List1, ?List2)
nextto(?X, ?Y, ?List), last(?List, ?Last)
nth0(?Index, ?List, ?Elem), nth1(?Index, ?List, ?Elem)
max_member(-Max, +List), min_member(-Max, +List),
sum_list(+List, -Sum)
3


Kiểm tra hoạt động
1 ?- member(3,[2,4,3,5]).
true .
2 ?- member([3],[2,4,3,5]).
false.
3 ?- member(3,[2,4,[3,2],5]).
false.
4 ?- member([3,_],[2,4,[3,2],5]).
true .
5 ?- member([3|T],[2,4,[3,2],5]).
T = [2] .
6 ?- delete([2,4,3,5],3,X).

X = [2, 4, 5].

4


Kiểm tra hoạt động
1 ?- append([2,4,5],[3,4,5,6],X).
X = [2, 4, 5, 3, 4, 5, 6].
4 ?- select(3,[2,3,4],X).
X = [2, 4] .
5 ?- last([a,f,d,b,c],X).
X = c.
Hãy tìm phần tử đứng thứ 3 trong danh sách
6 ?- nextto(3,X,[2,4,3,5,6]).
X = 5 .
Hãy tìm phần tử đứng trước số 4 trong danh sách
sau
[3,5,4,6,8,4,7].
7 ?- sum_list([3,5,4,6,8,4,7],X).
X = 37.

5


• Ví dụ1:
– Viết chương trình đếm số phần tử của 1 danh sách
size([],0).
size([H|T],N) :- size(T,N1), N is N1+1.
37 ?- size([a,3,d,4,v],X).
X = 5.

• Bài tập 1: tính tổng một danh sách (mysum)

6


Các phép tính số học
Các phép tính số học +,-,* và /.
Các phép so sánh <, >, =<, >=, =:=
(equals), =\=
Ví dụ:
?- 5<7,integer(4).
true.
?- 4+3=:=7.
true.

7


Suy diễn lùi (BackTracking)
Chẳng hạn ta có định nghĩa vi từ bigger
sau
bigger(N,M):N < M, write(‘The bigger number is ‘), write(M).
bigger(N,M):N > M, write(‘The bigger number is ‘), write(N).
bigger(N,M):N =:= M, write(‘Numbers are the same‘).

Bây giờ ta truy vấn
?- bigger(5,4).
Prolog làm gì?
8



Tìm vị từ
?- bigger(5,4).
bigger(N,M):N < M,
write(‘The bigger number is ‘), write(M).
bigger(N,M):N > M,
write(‘The bigger number is ‘), write(N).
bigger(N,M):N =:= M,
write(‘Numbers are the same‘).

9


bigger(5,4).
bigger(5,4):- Backtrack
5 < 4,  fails
write(‘The bigger number is ‘),
write(M).
bigger(N,M):N > M,
write(‘The bigger number is ‘),
write(N).
bigger(N,M):N =:= M,
write(‘Numbers are the same‘).
10


|?- bigger(5,4).
bigger(N,M):N < M,
write(‘The bigger number is ‘),
write(M).

bigger(5,4):5 > 4,  succeeds, go on with body.
write(‘The bigger number is ‘), write(N).
bigger(N,M):Đến dấu chấm
N =:= M,
= thành công
write(‘Numbers are the same‘).

11


Backtracking – Suy diễn lùi
?- bigger(5,5).

 If our query only matches the final clause

bigger(N,M):N < M,
write(‘The bigger number is ‘), write(M).
bigger(N,M):N > M,
write(‘The bigger number is ‘), write(N).
bigger(5,5):5 =:= 5,  Đã biết trước là không xảy ra.
write(‘Numbers are the same‘).

Clauses should be ordered according to specificity
Most specific at top
Universally applicable at bottom
12


Đích trung gian
1) drinks(alan,beer).

2) likes(alan,coffee).
3) likes(heather,coffee).
4) likes(Person,Drink):drinks(Person,Drink).  Đích trung gian
5) likes(Person,Somebody):likes(Person,Drink),
 đệ quy
likes(Somebody,Drink). 

13


Đệ quy
• Một mệnh đề đệ quy là mệnh đề đệ quy là
mệnh đề sử dụng chính nó để định nghĩa nó.
• Một mệnh đề đệ quy sẽ bị lặp vô hạn nếu
không có điều kiện thoát. Vì vậy phải có
định nghĩa trường hợp cụ thể không đệ quy
ngay trước mô tả đệ quy.
• Ví dụ: size([],0).
• Lập trình viên prolog thường sử dụng đệ
quy gián tiếp
a(X):-b(Y).
b([]) is 1. %điều kiện thoát đệ quy bên dưới
b(Y):-a(X).
14


Ví dụ 2: Bài toán tháp Hà nội
Đế đặt nằm ngang; các cột thẳng đứng. Các đĩa đặt theo
thứ tự từ lớn đến nhỏ từ thấp lên cao; tạo nên một Tòa
tháp. Trò chơi đòi hỏi di chuyển các đĩa, bằng cách đặt

chúng vào cột bên cạnh, một đĩa trong một di chuyển,
theo luật sau:
I. -- Sau mỗi di chuyển, các đĩa đều nằm trên một, hai,
hoặc ba cột, theo thứ tự từ lớn đến nhỏ từ thấp đến cao.
II. -- Đĩa trên cùng của một trong ba cột đĩa được đặt vào
cột rỗng.
III. -- Đĩa trên cùng của một trong ba cột đĩa được đặt lên
một cột đĩa khác, nếu đĩa này nhỏ hơn các đĩa của cột này.

15


Lưu đoạn code sau vao file hanoi.pl
move(1,X,Y,_) :write('chuyen dia tren cung tu '),
write(X), write(' sang '),write(Y), nl.
move(N,X,Y,Z) :- N>1, M is N-1,
move(M,X,Z,Y), move(1,X,Y,_),move(M,Z,Y,X).
55 ?- [hanoi].
% hanoi compiled 0.00 sec, 1 clauses
true.
56 ?- move(5,giua,trai,phai).
chuyen dia tren cung tu giua sang trai
chuyen dia tren cung tu giua sang phai
chuyen dia tren cung tu trai sang phai
16


Cắt “!”
Giả sử có các vị từ a,b và c
a(X, Y) :- b(X), !, c(Y).

b(1).

b(2).

b(3).

c(1).

c(2).

c(3).

Truy vấn
?- a(Q,P). Sẽ hoạt động như thế nào

17


Cắt “!”
?- a(Q,P).
Q = P, P = 1 ;
Q = 1,
P = 2 ;
Q = 1,
P = 3.
vì có dấu ! (cut)

18



Cắt “!”
• Cắt không làm thay đổi kết quả truy vấn
• Cắt chỉ giới hạn số phép quay lui khi
điều kiện ngay trước đó đã được thỏa
mãn.

– Nhanh hơn
– Chống đệ quy vô hạn

19


Bài tập 2
Sắp xếp một danh sách theo thứ tự tăng dần.
• Bubble sort? QuickSort? MergeSort?
•Prolog “ưa” các giải thuật đệ quy => QS và
MS dễ viết hơn!

20


Quicksort
quicksort([X|Xs],Ys) :  partition(Xs,X,Left,Right),
  quicksort(Left,Ls),
  quicksort(Right,Rs),
  append(Ls,[X|Rs],Ys).
quicksort([],[]).
partition([X|Xs],Y,[X|Ls],Rs) :  X <= Y, partition(Xs,Y,Ls,Rs).
partition([X|Xs],Y,Ls,[X|Rs]) :  X > Y, partition(Xs,Y,Ls,Rs).
partition([],Y,[],[]).

append([],Ys,Ys).
append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs). 21


Mergesort
mergesort([],[]).    /* covers special case */
mergesort([A],[A]).
mergesort([A,B|R],S) :-      split([A,B|R],L1,L2),
   mergesort(L1,S1),    mergesort(L2,S2),   
merge(S1,S2,S). split([],[],[]). split([A],[A],
[]). split([A,B|R],[A|Ra],[B|Rb]) :- 
split(R,Ra,Rb). merge(A,[],A). merge([],B,B).
merge([A|Ra],[B|Rb],[A|M]) :-  A =< B, merge(Ra,
[B|Rb],M).
merge([A|Ra],[B|Rb],[B|M]) :- 
A > B,  merge([A|Ra],Rb,M).
Truy vấn: ?- mergesort([4,3,6,5,9,1,7],S).
S=[1,3,4,5,6,7,9]
22


Bài tập
1. Viêt một chương trình để bỏ ba phần tử
đầu của một danh sách.
2. Định nghĩa hai vị từ :
even_length( List ) và odd_length( List )
để kiểm tra số các phần tử của một danh
sách là chẵn hay lẻ.
Ví dụ danh sách :
even_length([ a, b, c, d ]) là true

even_length([ a, b, c]) là false.
23


3. Viêt chương trình Prolog kiểm tra một
danh sách có phải là một tap hợp con của
một danh sách khác không ?
?- subset2([4,3],[2,3,5,4]).
Yes
4. Viết chương trình Prolog tìm phần tử
lớn nhất và phần tủ nhỏ nhất trong một
danh sách các số.
?- maxmin([3,1,5,2,7,3],Max,Min).
Max = 7
Min = 1
Yes

24


5. Viết chương trình Prolog
danh sách có rời nhau không

kiểm tra hai

?- disjoint([a,b,c],[d,g,f,h]).
Yes
?- disjoint([a,b,c],[f,a]).
No
6. Viết chương trình Prolog tìm phần tử X

đầu tiên trong danh sách L

25


×