CHƯƠNG 3 : BÀI TOÁN ỨNG DỤNG
3.1. Ứng dụng F* vàocác bài toán lập trình
3.1.1. Ứng dụng trong bài toán sắp xếp mảng nổi bọt (Buble sort)
Hiện nay với các phương pháp lập trình hàng ngày, chúng ta có thể dễ dàng viết các bài toán để giải quyết các vấn đề như sắp xếp mảng, tính toán các số lớn, xử lý các file dữ liệu, ứng dụng web… Vậy F* giúp ích gì, vì sao nên dùng F* trong các bài toán đó. Bắt đầu với bài toán chứng minh thuật toán phân loại, sắp xếp các phần tử trong mảng theo thứ tự tăng dần. Mở đầu với bài toán về thuật toán sắp xếp nổi bọt.
1module BubbleSort
2val length:list 'a -> Tot nat 3letrec length l =
4 match l with
5 |[]->0
6 |_::tl ->1+ length tl
7val swap : l:listint-> Tot (listint)(decreases (length l)) 8 letrec swap l = 9 match l with 10 |[]->[] 11 |x::[]-> x::[] 12 |x::y::xs ->if x > y then 13 y::(swap (x::xs)) 14 else 15 x::(swap (y::xs))
16 valsort :listint-> count:nat -> Tot (listint)(decreases count)
17 letrec sort x count =
18 if count >1then sort (swap x)(count -1) 19 else x
20valbubbleSort :listint-> Tot (listint) 21let bubbleSort x = sort x (length x)
Trong F*, ta cần định nghĩa rõ ràng kiểu dữ liệu của tham số truyền vào trong một hàm, có thể thêm các hàm chứng minh ví dụ nhưval swap : l:listint-> Tot (listint)(decreases (length l)).Ta có thể nhận thấy khi sử dụng hàm swap, lượng phần tử trong danh sách l sẽ lần lượt giảm dần do sử dụng đệ quy lần lượt với các phần tử trong mảng. Tương tự như vậy tại hàm sort, ta có valsort :listint-> count:nat -> Tot (listint)(decreases count)trong đó giá trị của biến count sẽ lần lượt giảm sau mỗi lần gọi đệ quy. Như vậy hàm của chúng ta có tính logic đúng.
Ta có hàm length để thực hiện tính toán số lượng phần tử trong mảng, swap thực thi nhiệm vụ đổi chỗ các phần tử trong mảng nếu phần tử một lớn hơn phần tử hai thì đổi chỗ phần tử một cho phần tử hai. Hàm sort để thực hiện sắp xếp lại các phần tử trong mảng từ nhỏ đến lớn. Sử dụng bubbleSort là hàm truyền các tham số đầu vào cần thiết cho hàmsort. Việc định nghĩa các mệnh đề giảm dần khá cần thiết trong F* để có thể kết thúc
được chứng minh trong F* hoặc nếu không muốn gặp phải những báo lỗi như “not
compatible with the annotated type” khi biên dịch với F*. Với ví dụ trên ta cần định nghĩa
các mệnh đề giảm dần cho hàm swap và sort. Chúng ta có thể kiểm chứng đoạn mã trên thông qua việc biên dịch sang ngôn ngữ OCaml và thực hiện nhập các giá trị đầu vào.
Hình 3.1: Kết quả cho bài toán sắp xếp nổi bọt