300 likes | 570 Views
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. 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. Xử lý danh sách.
E N D
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
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
Xử lý danh sách Danhsách (list) làcấutrúcdữliệuquantrọng. • Biểudiễndanhsách [X], [a,b,c], [], [Head|Tail]. • Cácvị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)
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].
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.
Ví dụ1: • Viếtchươngtrìnhđếmsốphầntửcủa 1 danhsá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àitập 1: tínhtổngmộtdanhsách (mysum)
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.
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ì?
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‘).
Backtrack bigger(5,4). bigger(5,4):- 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‘).
|?- 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 =:= M, write(‘Numbers are the same‘). Đến dấu chấm = thành công
Clauses should be ordered according to specificity Most specific at top Universally applicable at bottom 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, • write(‘Numbers are the same‘). Đã biết trước là không xảy ra.
Đí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).
Đệ quy • Mộtmệnhđềđệquylàmệnhđềđệquylàmệnhđềsửdụngchínhnóđểđịnhnghĩanó. • Mộtmệnhđềđệquysẽbịlặpvôhạnnếukhôngcóđiềukiệnthoát. Vìvậyphảicóđịnhnghĩatrườnghợpcụthểkhôngđệquyngaytrướcmôtảđệquy. • Vídụ: size([],0). • Lậptrìnhviên prolog thườngsửdụngđệquygiántiếp a(X):-b(Y). b([]) is 1. %điềukiệnthoátđệquybêndưới b(Y):-a(X).
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.
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
Cắt “!” Giảsửcócácvịtừa,bvà c a(X, Y) :- b(X), !, c(Y). b(1). b(2). b(3). c(1). c(2). c(3). Truyvấn ?- a(Q,P). Sẽhoạtđộngnhưthếnào
Cắt “!” ?- a(Q,P). Q = P, P = 1 ; Q = 1, P = 2 ; Q = 1, P = 3. vì có dấu ! (cut)
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
Bài tập 2 Sắpxếpmộtdanhsáchtheothứtựtăngdần. • Bubble sort? QuickSort? MergeSort? • Prolog “ưa” cácgiảithuậtđệquy => QS và MS dễviếthơn!
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).
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]
Bài tập • Viêtmộtchươngtrìnhđểbỏbaphầntửđầucủamộtdanhsách. • Địnhnghĩahaivịtừ : even_length( List ) vàodd_length( List ) đểkiểmtrasốcácphầntửcủamộtdanhsáchlàchẵn hay lẻ. Vídụdanhsách : even_length([ a, b, c, d ]) là true even_length([ a, b, c]) là false.
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
5. Viết chương trình Prolog kiểm tra hai danh sách có rời nhau không ?- 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
Bài kế tiếp Cơ sở dữ liệu Xuất nhập
Cơ sở dữ liệu • Tổchứccơsởdữliệudướidạngbảng • Cácbảngcómốiliênkết (quanhệràngbuộc) • Vídụ: ‘bảng’ individual individual( tom, smith, date(7, may, 1960), work(microsoft, 30000) ). individual( ann, smith, date(9, avril, 1962), inactive).
‘bảng’ family family(individual(…), individual(…), [individual(…)]). Vớiámchỉngôi 1 làchồng, ngôi 2 làvợ, ngôi 3 làdanhsáchcác con. family(individual( tom, smith, date(7, may, 1960), work(microsoft, 30000) ), individual( ann, smith, date(9, avril, 1962),inactive), [ individual( roze, smith, date(16, june, 1991), inactive), individual( eric, smith, date(23, march, 1993), inactive) ] ). husban( X ) :- % X là chồng family( X , _ , _ ). wife( X ) :- % X là vợ family( _, X , _ ). children( X ) :- % X làmộtngườicon, family( _, _ , Children ), member( X, Children ).
Ta định nghĩa một số vị từ để tiện truy vấn exist( Individual ) :- % mọi thành viên của gia dình husban( Individual ) ; wife( Individual ) ; chidren( Individual ). % dấu ; là hoặc, dấu , là và!!! dateofbirth( individual( _ , _, Date , _ ), Date ). salary( individual( _ , _, _ , work( _ , S ) ), S ). salary( individual( _ , _, _ , inactive ), 0 ). Tại sao phải có 2 định nghĩa salary?
Truy vấn dữ liệu Cáclệnhtruyvấnsauđâysẽtrảlạinhữngthông tin gì? ?- exist( individual( Firstname, Lastname, _ , _ ) ). ?- chidren( X ), dateofbirth( X, date( _ , _ , 1991 )). ?- wife( individual( Firstname, Lastname, _ , work( _, _ ) ) ). Hãyviếtcáclệnhtruyvấncácthông tin sau: • Tìmnhữngngườisinhtrước 1975 khôngcóviệclàm • Tìmnhữngngườisinhtrước 1970 cóthunhậptrên 10000 • Tìmnhữnggiađìnhcótrên 3 người con.