II. Sử dụng các cấu trúc
II.2 Trừu tượng hoá dữ liệu
Trừu tượng hoá dữ liệu (data abstraction) được xem là cách tổ chức tự nhiên (một cách có thứ cấp) những thành phần khác nhau trong cùng những đơn vị thông tin, sao cho về mặt ý niệm, người sử dụng có thể hiểu được cấu trúc bên trong. Chương trình phải dễ dàng truy cập được vào từng thành phần dữ liệu. Một cách lý tưởng thì người sử dụng không nhìn thấy được những chi tiết cài đặt các cấu trúc này, người sử dụng chỉ quan tâm đến những đối tượng và quan hệ giữa chúng. Với mục đích đó, Prolog phải có cách biểu diễn thông tin phù hợp.
Để tìm hiểu cách Prolog giải quyết, ta quay lại ví dụ cơ sở dữ liệu gia đình trong mục trước đây. Mỗi gia đình là một nhóm các thông tin khác nhau về bản chất, mỗi người hay mỗi gia đình được xử lý như một đối tượng độc lập.
Giả thiết rằng mỗi gia đình được biểu diễn như Hình II.1. Bây giờ ta tiếp tục định nghĩa các quan hệ để có thể tiếp cận đến các thành phần của gia đình mà không cần biết chi tiết. Những quan hệ này được gọi là các bộ chọn
(selector), vì chúng chọn những thành phần nào đó. Mỗi bộ chọn sẽ có tên là tên thành phần mà nó chọn ra, và có hai tham đối : đối tượng chứa thành phần được chọn và bản thân thành phần đó :
selector_relation( Object, Selected_component ) Sau đây là một số ví dụ về các bộ chọn :
husban( family( Husban, _ , _ ), Husban ).
wife( family( _ , Wife, _ ), Wife ).
chidren( family( _ , _ , ChidrenList ), ChidrenList ).
Ta cũng có thể định nghĩa những bộ chọn chọn ra những người con đặc biệt như con trưởng, con út và con thứ N trong gia đình :
eldest( Family, Eldest ) :- % người con trưởng
chidren(Family, [ Eldest | _ ] ).
cadet( Family, Eldest ) :- % người con út
chidren( Family, [ Eldest | _ ] ).
Chọn ra một người con bất kỳ nào đó :
nth_child( N, Family, Chidren ) :- % người con thứ N trong gia đình
Kỹ thuật lập trình Prolog 137
% phần tử thứ N của một danh sách
nth_member( N, ChidrenList, Chidren ).
Từ biểu diễn cấu trúc minh hoạ trong Hình II.1, sau đây là một số bộ chọn nhận tham đối là một thành viên trong gia đình (individual) :
lastname( individual( _ , Lastname, _ , _ ), Lastname ). % tên gia đình (họ)
firstname( individual( Firstname, _ , Wife, _ ), Firstname ). % tên riêng
born( individual( _ , _ , Date, _ ), Date ). % ngày sinh
Làm cách nào để có thể áp dụng các bộ chọn ? Mỗi khi các bộ chọn đã được định nghĩa, ta không cần quan tâm đến cách biểu diễn những thông tin có cấu trúc. Để tạo ra và để thao tác trên những thông tin cấu trúc, chỉ cần biết tên các bộ chọn và sử dụng chúng trong chương trình. Với phương pháp này, các biểu diễn phức tạp cấu trúc dữ liệu sẽ dễ dàng hơn so với phương pháp mô tả đã xét.
Ví dụ, người sử dụng không cần biết những người con trong gia đình được lưu giữ trong một danh sách. Giả sử rằng ta muốn hai người con Johan Smith và Eric Smith cùng thuộc một gia đình, và Eric là em thứ hai của Johan. Ta có thể sử dụng bộ chọn để định nghĩa hai cá thể, được gọi là Individual1 và Individual2, và định nghĩa gia đình như sau :
% Johan Smith
lastname( Individual1, smith ), firstname( Individual1, johan ).
% Eric Smith
lastname( Individual2, smith ), firstname( Individual1, eric ),
husban( Family, Individual1 ).
nth_child( 2, Family, Individual2 ).
Việc sử dụng các bộ chọn làm thay đổi dễ dàng một chương trình Prolog. Giả sử ta muốn thay đổi dữ liệu của một chương trình, ta chỉ cần định nghĩa lại các bộ chọn, phần còn lại của chương trình vẫn hoạt động như cũ.