Các công cụ kiểm chứng hiện nay hay dùng như Spin, Kronos, NuSMV,… Công cụ Spin mặc dù rất đơn giản, gọn nhẹ nhưng có tầm ảnh hưởng lớn trong phát triển phần mềm cho các hệ thống phức tạ
Trang 1TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
NGUYỄN THỊ LOAN
KIỂM CHỨNG TÍNH ĐÚNG ĐẮN HỆ THỐNG TÍNH TOÁN CỦA CHƯƠNG TRÌNH BẰNG KIỂM DUYỆT MÔ HÌNH
Ngành: Công nghệ thông tin
Chuyên ngành: Công nghệ phần mềm
Mã số: 60 48 10
TÓM TẮT LUẬN VĂN THẠC SĨ
Hà Nội - 2012
Trang 2MỤC LỤC
LỜI CẢM ƠN 0
LỜI CAM ĐOAN Error! Bookmark not defined MỤC LỤC 1
DANH MỤC VIẾT TẮT 4
DANH MỤC CÁC BẢNG 5
DANH MỤC HÌNH VẼ 6
MỞ ĐẦU 7
1 Đặt vấn đề 7
2 Nội dung nghiên cứu 7
3 Phương pháp nghiên cứu 7
4 Cấu trúc luận văn 8
CHƯƠNG 1: CƠ SỞ LÝ THUYẾT 9
1.1 Khái niệm và ý nghĩa của kiểm duyệt mô hình 9
1.2 Quy trình hoạt động của kiểm duyệt mô hình 10
1.3 Đặc trưng của kiểm duyệt mô hình 11
1.3.1 Mô hình hóa (Modeling) 11
1.3.2 Thực thi chương trình (Running the model checker) 12
1.3.3 Phân tích (Analysis) 12
1.4 Điểm mạnh và điểm yếu của kiểm duyệt dựa trên mô hình 13
1.5 Sử dụng logic thời gian (Temporal Logic) mô tả các thuộc tính cần kiểm chứng 14
1.5.1 Logic thời gian (Temporal Logic) 14
1.5.1.1 Cú pháp của LTL 14
1.5.1.2 Ngữ nghĩa 15
1.5.1.3 Sự tương đương của công thức LTL 16
1.5.1.4 Toán tử Weak Until – W 16
1.5.2 Các thuộc tính cần kiểm chứng 17
1.5.2.1 Thuộc tính an toàn (Safety) 17
1.5.2.2 Thuộc tính sống (Liveness) 17
1.5.2.3 Thuộc tính công bằng (Fairness) 17
1.6 Máy trạng thái hữu hạn 18
1.6.1 Định nghĩa máy trạng thái hữu hạn 18
1.6.2 Các máy trạng thái hữu hạn trao đổi thông tin 19
CHƯƠNG 2: GIỚI THIỆU VỀ SPIN VÀ PROMELA 20
2.1 Ngôn ngữ Promela 20
2.1.1 Cấu trúc chương trình Promela 20
Trang 32.1.2 Biến 21
2.1.3 Kiểu dữ liệu 21
2.1.3.1 Các kiểu dữ liệu cơ bản trong Promela 21
2.1.3.2 Kiểu dữ liệu có cấu trúc 22
2.1.3.3 Kiểu mtype 24
2.1.4 Định danh, hằng, và biểu thức 25
2.1.5 Tiến trình 26
2.1.5.1 Tiến trình process 26
2.1.5.2 Tiến trình init 26
2.1.5.3 Active proctype 27
2.1.6 Run và atomic 28
2.1.6.1 Run và tiến trình init() 28
2.1.6.2 Atomic 28
2.1.7 Cấu trúc điều khiển 30
2.1.7.1 Lệnh lựa chọn if 30
2.1.7.2 Lệnh lặp do 30
2.1.7.3 Lệnh nhảy goto 31
2.2 Công cụ Spin 31
2.2.1 Kiểm chứng chương trình trong Spin 31
2.2.1.1 Đặc trưng của SPIN 31
2.2.1.2 Mô hình hệ thống trong SPIN 32
2.2.1.3 Cấu trúc của Spin 32
2.2.1.4 Giả lập ngẫu nhiên 33
2.2.1.5 Kiểm chứng (Verify) 34
2.2.2 Giao diện người dùng Xspin 36
2.2.3 Logic thời gian tuyến tính (LTL - Linear Temporal Logic) trong Spin 41
2.2.3.1 Cú pháp Logic thời gian tuyến tính 42
2.2.3.2 Biểu diễn tính chất bất biến của hệ thống bằng LTL 42
2.2.4 Cấu trúc Never claim 43
CHƯƠNG 3: ỨNG DỤNG 44
3.1 Xây dựng biến và tiến trình đồng hồ 44
3.2 Hệ thống báo động, báo cháy mức trừu tượng 48
3.2.1 Mô tả hệ thống mức trừu tượng 48
3.2.2 Mô hình Promela cho hệ thống báo động, báo cháy mức trừu tượng và kiểm chứng thuộc tính đơn giản 49
3.3 Hệ thống báo động, báo cháy mức 2 52
Trang 43.3.1 Mô tả hệ thống mức 2 52
3.3.2 Mô hình Promela cho hệ thống báo động, báo cháy mức 2 và kiểm chứng thuộc tính đơn giản 53
KẾT LUẬN 58
TÀI LIỆU THAM KHẢO 60
PHỤ LỤC 61
Trang 5DANH MỤC VIẾT TẮT
TỪ VIẾT
CTL Branching Temporal Logic Logic thời gian rẽ nhánh FSM Finite State Machine Máy trạng thái hữu hạn LTL Linear Temporal Logic Logic thời gian tuyến tính VHDL Very High Speed Intergrated Circuit Mạch tích hợp tốc độ cao FIFO First In First Out Vào trước ra trước
Trang 6DANH MỤC CÁC BẢNG
Bảng 2.1: Các kiểu dữ liệu cơ bản trong Promela 21
Bảng 2.2: Các toán tử trong Promela 25
Bảng 2.3: Các phép toán mệnh đề trong LTL 42
Bảng 2.4: Các phép toán thời gian của LTL 42
Trang 7DANH MỤC HÌNH VẼ
Hình 1.1: Sơ đồ hoạt động của phương pháp kiểm duyệt mô hình 10
Hình 1.2 Ví dụ về mô hình 12
Hình 1.3: Ví dụ máy hữu hạn trạng thái dạng đồ thị 18
Hình 1.4: Truyền thông điệp đồng bộ hóa (!m, ?m), (?m, !m) 19
Hình 1.5: Đồng bộ hóa thông điệp 19
Hình 2.1: mô hình của hệ thống trong Spin 32
Hình 2.2: Cấu trúc của Spin 33
Hình 2.3: Màn hình cửa sổ chính của XSpin 37
Hình 2.4: Các chức năng trong menu Run 37
Hình 2.5: Cửa sổ chính chức năng Set Simulation Parameters 38
Hình 2.6: Cửa sổ khi chạy chức năng Run Simulation 39
Hình 2.7: Cửa sổ chính chức năng Set Verification Parameters 40
Hình 2.8: Cửa sổ khi chạy chức năng Run Verification 40
Hình 2.9: Cửa sổ khi chạy chức năng LTL Property Manager 41
Bảng 2.3: Các phép toán mệnh đề trong LTL 42
Bảng 2.4: Các phép toán thời gian của LTL 42
Hình 3.1: Kiến trúc trừu tượng của hệ thống báo động, báo cháy 48
Hình 3.2: Kết quả khi mô phỏng mô hình hệ thống báo động, báo cháy mức trừu tượng 51
Hình 3.3: Kết quả kiểm chứng mô hình hệ thống báo động, báo cháy 52
Hình 3.4: Kiến trúc mức 2 của hệ thống báo động, báo cháy 53
Hình 3.5: Kết quả khi mô phỏng mô hình hệ thống báo động, báo cháy mức trừu tượng 56
Hình 3.6: Kết quả kiểm chứng mô hình hệ thống báo động, báo cháy 57
Trang 8MỞ ĐẦU
1 Đặt vấn đề
Ngày nay chúng ta phụ thuộc rất nhiều vào hệ thống máy tính (phần cứng
và phần mềm) cả trong sản xuất lẫn đời sống hàng ngày Các hệ thống này cần phải đảm bảo sự tin cậy và an toàn khi sử dụng Do đó chúng cần phải được kiểm duyệt kỹ càng ngay từ mô hình của hệ thống để đảm bảo hệ thống hoạt động chính xác tránh gây thiệt hại cả về con người lẫn tiền của Hơn nữa việc áp dụng kỹ thuật kiểm chứng hệ thống qua mô hình hệ thống sẽ làm tăng hiệu quả kinh tế bởi nhờ có kiểm chứng mô hình mà nhà sản xuất có thể xác định sớm các lỗi trong hệ thống nên chi phí vào quá trình kiểm thử hoặc khắc phục lỗi sẽ giảm đáng kể
Kỹ thuật kiểm chứng mô hình đã được sử dụng để kiểm chứng cho các mô hình hệ thống trong thực tế Tuy nhiên để phát huy được hết hiệu quả của kỹ thuật này cần có công cụ kiểm chứng đi kèm để hỗ trợ quá trình kiểm chứng Các công cụ kiểm chứng hiện nay hay dùng như Spin, Kronos, NuSMV,… Công cụ Spin mặc dù rất đơn giản, gọn nhẹ nhưng có tầm ảnh hưởng lớn trong phát triển phần mềm cho các hệ thống phức tạp như hệ thời gian thực, hệ thống nhúng, hệ tương tác, …
Từ thực tiễn đó, chúng tôi chọn đề tài “Kiểm chứng tính đúng đắn hệ thống tính toán của chương trình bằng kiểm duyệt mô hình” nhằm mục đích là tiếp cận, nghiên cứu phương pháp kiểm chứng mô hình, dùng công cụ kiểm chứng Spin và ngôn ngữ mô hình hóa Promela để kiểm chứng tính đúng đắn của hệ thống
2 Nội dung nghiên cứu
Nội dung đề tài nghiên cứu về kỹ thuật kiểm chứng mô hình (Model Checking), dùng công cụ Spin để thực hiện kiểm chứng mô hình hệ thống báo động, báo cháy, sử dụng ngôn ngữ mô hình hóa Promela để mô hình hóa hệ thống báo động, báo cháy, và mô tả các thuộc tính cần kiểm chứng qua Logic thời gian tuyến tính để kiểm chứng tính đúng đắn của hệ thống báo động, báo cháy qua mô hình của nó
3 Phương pháp nghiên cứu
Phương pháp thu thập tài liệu: Các thông tin sử dụng trong luận văn được thu thập từ các nguồn: Sách tham khảo, giáo trình, giáo án, các bài báo
Phương pháp phân tích: Dựa trên các tài liệu thu thập được, phân tích, đánh giá và đưa ra kết luận
Trang 94 Cấu trúc luận văn
Chương 1 trình bày về cơ sở lý thuyết của kiểm duyệt mô hình (Model checking)
Chương 2 trình bày về công cụ Spin, giao diện Xspin, và ngôn ngữ mô hình hóa Promela
Chương 3 xây dựng tiến trình đồng hồ, mô hình hóa hệ thống báo động, báo cháy, kết hợp tiến trình đồng hồ với kỹ thuật kiểm duyệt mô hình để kiểm chứng tính đúng đắn của hệ thống đó
Phần kết luận tóm tắt kết quả đã đạt được, kết luận, những hạn chế cũng như hướng phát triển trong tương lai của đề tài
Trang 10CHƯƠNG 1: CƠ SỞ LÝ THUYẾT
Trong chương 1 sẽ trình bày các khải niệm cơ bản về kỹ thuật kiểm duyệt
mô hình (Model Checking), và giới thiệu về logic thời gian tuyến tính cũng như máy trạng thái hữu hạn
1.1 Khái niệm và ý nghĩa của kiểm duyệt mô hình
Theo Clarke và Emerson – 1981, kiểm duyệt mô hình được định nghĩa:
“Kiểm duyệt mô hình là một kỹ thuật được tự động hóa nhằm đưa ra mô hình hữu hạn trạng thái của hệ thống và thuộc tính hình thức, kỹ thuật này sẽ kiểm tra có hay không thuộc tính được thõa mãn bởi mô hình của hệ thống” [5] Trong giai đoạn thiết kế phần mềm và phần cứng của các hệ thống phức tạp hiện nay, các chuyên gia dành rất nhiều thời cho việc kiểm chứng hơn là việc xây dựng hệ thống Có rất nhiều kỹ thuật đã được tìm ra để làm tăng phạm vi ứng dụng của kiểm chứng Các phương pháp hình thức là một trong những kỹ thuật đó Nó được tích hợp vào việc kiểm chứng trong quá trình thiết kế, để đưa
ra những kỹ thuật kiểm chứng hiệu quả và làm giảm thời gian kiểm chứng hệ thống Một trong những phương pháp hình thức mạnh mẽ nhất là kiểm duyệt mô hình [1, 2]
Kỹ thuật kiểm duyệt mô hình miêu tả hành vi của hệ thống bằng một phương pháp toán học chính xác và rõ ràng Một mô hình hệ thống chính xác có thể giúp chúng ta phát hiện ra những gì chưa đầy đủ, mơ hồ và không nhất quán trong đặc tả hệ thống, điều này thường được phát hiện sau giai đoạn thiết kế Do
đó cần kỹ thuật kiểm duyệt mô hình để làm rõ những điều nêu trên trước giai đoạn thiết kế Các mô hình của hệ thống thường được đi kèm với những thuật toán mà có thể giúp chúng ta tìm ra tất cả các trạng thái của mô hình hệ thống
đó Nhờ có sự nghiên cứu phát triển về thuật toán và cấu trúc dữ liệu, cùng với khả năng của máy tính ngày càng nhanh và dung lượng lưu trữ ngày càng cao, những kỹ thuật dựa trên mô hình đã cực kỳ phát triển và không chỉ áp dụng trong những ví dụ đơn giản mà hiện nay đã được ứng dụng vào những bản thiết
Mô hình của hệ thống thông thường được sinh ra tự động từ một sự mô tả
mô hình được đặc tả trên các ngôn ngữ lập trình như C, Java hoặc ngôn ngữ mô
tả phần cứng như Verilog Các thuộc tính nói lên rằng hệ thống nên làm những
Trang 11gì, và không nên làm gì, nhưng ngược lại bản mô tả mô hình tập trung vào hệ thống hành động như thế nào Công cụ kiểm chứng có khả năng kiểm tra mọi trạng thái của hệ thống để kiểm tra xem chúng có hay không thỏa mãn thuộc tính mong muốn
Kỹ thuật kiểm duyệt mô hình có nhiều phiên bản Phiên bản kể đến đầu tiên
là dùng kỹ thuật kiểm duyệt mô hình để mô hình hóa và kiểm chứng hệ thống không có ràng buộc thời gian, tiếp đến là ứng dụng kỹ thuật này để kiểm chứng
hệ thống có ràng buộc thời gian và hệ xác suất Tuy nhiên với việc tìm hiểu và dùng kỹ thuật kiểm duyệt mô hình để kiểm chứng hệ thống không có ràng buộc thời gian sẽ đơn giản hơn Do đó trong luận văn tác giả sẽ nghiên cứu và sử dụng phiên bản này kết hợp với kỹ thuật xây dựng biến và tiến trình đồng hồ để kiểm chứng tính chất ràng buộc thời gian trong hệ thống báo động, báo cháy
1.2 Quy trình hoạt động của kiểm duyệt mô hình
Hình 1.1: Sơ đồ hoạt động của phương pháp kiểm duyệt mô hình [2]
Mô hình của hệ thống được xây dựng từ đặc tả của hệ thống Mô hình này thể hiện hành vi của hệ thống và có thể được viết bởi ngôn ngữ C, Java, hay các ngôn ngữ mô tả phần cứng
Trang 12`Sự đặc tả thuộc tính yêu cầu những gì hệ thống nên làm và những gì không nên làm trong khi mô hình mô tả hệ thống hoạt động như thế nào?
Kiểm duyệt mô hình sẽ kiểm tra tất cả các trạng thái hệ thống liên quan xem có thỏa mãn không, nếu không thỏa mãn sẽ đưa ra một phản ví dụ - một trạng thái của hệ thống không thỏa mãn - cho thấy cách đạt đến trạng thái không thỏa mãn, sử dụng phản ví dụ cùng với sự mô phỏng ta sẽ có được những thông tin gỡ lỗi và từ đó sẽ có được mô hình phù hợp
1.3 Đặc trưng của kiểm duyệt mô hình
Quá trình kiểm duyệt một mô hình có thể chia thành những pha như sau:
Pha mô hình hóa (Modeling): Xây dựng mô hình cho hệ thống bằng cách
mô hình hóa hệ thống sử dụng ngôn ngữ mô tả mô hình của công cụ kiểm duyệt Sau đó kiểm tra sự đúng đắn và đánh giá nhanh mô hình bằng sự mô phỏng Hình thức hóa thuộc tính cần được kiểm duyệt sử dụng ngôn ngữ đặc tả thuộc tính
Pha thực thi (Running): Sử dụng chương trình kiểm duyệt để kiểm tra tính hợp lệ của thuộc tính trên mô hình hệ thống vừa xây dựng
Pha phân tích (Analysis): Kiểm tra xem nếu thuộc tính được thỏa mãn thì kiểm tra thuộc tính tiếp theo (nếu còn) Nếu thuộc tính bị vi phạm thì tiến hành phân tích phản ví dụ bằng sự mô phỏng; Tinh chỉnh mô hình, bản thiết kế, hoặc thuộc tính; Lặp lại toàn bộ các pha Nếu tràn bộ nhớ thì cố gắng giảm bớt mô hình và thử lại
Sau đây, là chi tiết nội dung của từng pha:
1.3.1 Mô hình hóa (Modeling)
Để có thể áp dụng được kiểm duyệt mô hình cần yêu cầu đầu vào là một
mô hình của hệ thống và các thuộc tính đặc tả hình thức sẽ được kiểm chứng
Mô hình của hệ thống mô tả hành vi của nó một cách đúng đắn và rõ ràng Chúng thường được diễn tả bằng otomat hữu hạn trạng thái (finite state automata) Một otomat hữu hạn trạng thái gồm tập các trạng thái (states) và tập các phép chuyển (transitions) Các trạng thái chứa thông tin về giá trị hiện tại của các biến, của câu lệnh được thực thi trước đó, hoặc gì đó tương tự Các phép chuyển diễn tả làm thế nào hệ thống chuyển từ trạng thái này sang trạng thái khác Với các hệ thống thực tế, otomat hữu hạn trạng thái được diễn tả bằng ngôn ngữ mô tả mô hình như C, Java, VHDL,
Trang 13Hình 1.2 Ví dụ về mô hình [5]
Để tăng chất lượng của mô hình, cần có sự mô phỏng trước khi kiểm duyệt
mô hình có Sự mô phỏng này được sử dụng để loại bỏ những vấn đề đơn giản hơn trước khi kiểm duyệt Điều này giúp làm giảm thời gian cũng như chi phí
Và cuối cùng, để có thể kiểm duyệt chính xác Các thuộc tính nên được diễn đạt rõ ràng, ngắn gọn nhưng đầy đủ Do vậy, cần sử dụng một ngôn ngữ đặc tả thuộc tính Trong luận văn này chỉ tập trung vào cách sử dụng logic thời gian (temporal logic) như là ngôn ngữ đặc tả thuộc tính Thực chất, logic thời gian là sự mở rộng của logic mệnh đề với những toán tử biểu diễn hành vi của
hệ thống theo thời gian Logic thời gian hoàn toàn có khả năng biểu diễn những thuộc tính của hệ thống như sự đúng đắn chức năng (functional correctness), thuộc tính sống (liveness property), thuộc tính an toàn (safety property), thuộc tính công bằng (fairness property)
1.3.2 Thực thi chương trình (Running the model checker)
Sau khi có được mô hình của hệ thống và các thuộc tính, chúng ta cần sử dụng một công cụ kiểm chứng để kiểm tra các thuộc tính có thỏa mãn mô hình vừa xây dựng không Trong luận văn sẽ sử dụng công cụ kiểm chứng Spin để thực hiện điều đó
1.3.3 Phân tích (Analysis)
Sau pha thực thi kiểm chứng mô hình, cần phải phân tích kết quả đạt được Thường thì chúng ta có ba trường hợp xảy ra: Các thuộc tính có thỏa mãn hay không, hoặc mô hình quá lớn ngoài khả năng vật lý của bộ nhớ máy tính
Khi các thuộc tính được thõa mãn, mô hình đáp ứng được tất cả những thuộc tính mong muốn
inc
A modulo 3 counter
Trang 14Khi một thuộc tính không thỏa mãn, tức có thể xuất hiện lỗi trong mô hình, hoặc có thể do thuộc tính được hình thức hóa sai
Còn về khả năng thứ 3, mô hình quá lớn để có thể xử lý thì có rất nhiều giải pháp để khắc phục Tuy nhiên, giải pháp hiệu quả nhất là cố gắng làm giảm không gian trạng thái (state space) khi kiểm chứng
1.4 Điểm mạnh và điểm yếu của kiểm duyệt dựa trên mô hình
Kiểm duyệt mô hình có một vài điểm mạnh như [2]:
Là phương pháp kiểm chứng tổng quan được áp dụng cho các ứng dụng trong phạm vi lớn như hệ thống nhúng, công nghệ phần mềm, thiết kế phần cứng,…
Hỗ trợ kiểm duyệt cục bộ, các thuộc tính có thể được kiểm tra riêng lẻ,
từ đó tập chung kiểm duyệt các thuộc tính quan trọng trước mà không cần thiết đặc tả hệ thống hoàn chỉnh
Quá trình kiểm duyệt sau không ảnh hưởng đến các lỗi đã được phát hiện trước đó
Cung cấp các thông tin có ý nghĩa cho việc gỡ lỗi khi phát hiện một thuộc tính không thỏa mãn
Kiểm duyệt mô hình là tiềm năng của công nghệ “push – botton”, sử dụng kiểm duyệt mô hình làm tăng mức độ tương tác người dùng và chuyên môn
Kiểm duyệt mô hình dễ dàng tích hợp trong chu kỳ phát triển phần mềm, làm giảm thời gian phát triển phần mềm
Kiểm duyệt mô hình có nền tảng của toán học, nó dựa trên lý thuyết thuật toán đồ thị, cấu trúc dữ liệu và logic
Bên cạnh những ưu điểm trên, phương pháp kiểm duyệt mô hình cũng có những yếu điểm như [2]:
Kiểm duyệt mô hình chủ yếu phù hợp với các ứng dụng điều khiển, không phù hợp với các ứng dụng hướng dữ liệu do khối lượng dữ liệu thường tăng vô hạn
Kiểm duyệt mô hình kiểm chứng mô hình của hệ thống chứ không phải bản thân hệ thống, mọi kết quả đạt được là về mặt mô hình hệ thống, do
đó cần có những kỹ thuật khác hỗ trợ như kiểm duyệt để tìm ra lỗi chế tạo (trong phần cứng) và lỗi lập trình (phần mềm)
Kiểm duyệt mô hình chỉ kiểm chứng những thuộc tính được đặc tả
Việc sử dụng kiểm duyệt mô hình yêu cầu kinh nghiệm trừu tượng hóa
hệ thống thích hợp để đưa ra mô hình hệ thống theo logic thời gian
Trang 15Mặc dù có những hạn chế nhất định trên nhưng kiểm duyệt mô hình vẫn là
kỹ thuật hiệu quả để tìm ra lỗi thiết kế nhằm tạo ra hệ thống hoàn chỉnh nhất
1.5 Sử dụng logic thời gian (Temporal Logic) mô tả các thuộc tính cần kiểm chứng
1.5.1 Logic thời gian (Temporal Logic)
Các biểu thức temporal logic không chỉ xét đến những dãy trạng thái đơn,
mà còn xét đến những dãy trạng thái phức tạp trong đó từ một trạng thái có thể
có nhiều trạng thái ngay tiếp sau nó Trong các nghiên cứu về kiểm duyệt mô hình, có hai loại logic thời gian hay được xem xét là LTL (Linear Temporal Logic) và CTL (Banching Temporal Logic) [2]
LTL (Linear Temporal Logic): Logic thời gian tuyến tính Thời gian có cấu trúc tuyến tính, mỗi trạng thái chỉ có một trạng thái ngay tiếp sau nó
CTL (Branching Temporal Logic): Logic thời gian rẽ nhánh Thời gian có cấu trúc tuyến tính, mỗi trạng thái có nhiều trạng thái ngay tiếp sau nó Nhờ khả năng xét đến yếu tố thời gian, temporal logic đã được sử dụng rộng rãi trong công nghệ kiểm chứng phần mềm Temporal logic thường được
sử dụng để mô tả các thuộc tính cần kiểm chứng Trong khóa luận này xin trình bày về LTL (Linear Temporal Logic)
1.5.1.1 Cú pháp của LTL
Một công thức LTL được hình thành từ những mệnh đề nguyên tử (aAP),
các phép boolean như phép hội , phép phủ định , và hai phép thể thức (modality) đơn giản là (gọi là “next”) và ∪ (gọi là “until”) Thể thức là
toán tử một ngôi và yêu cầu một công thức LTL là tham đối Công thức φ thõa mãn tại thời điểm hiện tại, nếu φ thõa mãn ở bước tiếp theo Thể thức ∪là toán
tử trung tố một ngôi và yêu cầu hai công thức LTL là tham đối Công thức φ 1 ∪
φ 2 thỏa mãn tại thời điểm hiện tại, nếu có một vài thời điểm trong tương lai mà
φ 2 thõa mãn và φ 1 thõa mãn tại mọi thời điểm cho đến thời điểm tương lai đó
φ 1 φ 2 ( φ 1 φ 2 )
Trang 16Ngoài ra, bằng việc kết hợp hai toán tử ◊ và □, ta có các thể thức thời gian
mới Ví dụ như, □◊a (“always eventually a”) miêu tả thuộc tính mà tại bất kì thời điểm j đều có một thời điểm i j mà tại đó một trạng thái a được duyệt
Tức là trạng thái a được duyệt thường xuyên và vô hạn – infinitely often Tương
tự, phép đối ngẫu ◊□a có thể hiểu rằng từ một vài thời điểm j, chỉ có trạng thái a
được duyệt
□ ◊ φ “infinitely often φ”
◊ □ φ “eventually forever φ”
Ví dụ 1.1: Các thuộc tính được diễn tả bằng LTL
Thuộc tính hệ thống đèn giao thông:
Đối với đèn tín hiệu giao thông, thì có thuộc tính yêu cầu như sau “ khi đèn
đỏ, đèn không được chuyển sang xanh ngay lập tức” được diễn đạt dưới dạng
LTL:
Hoặc thuộc tính “một khi đèn đỏ, đèn luôn luôn cuối cùng thành xanh và
trước đó là đèn vàng ” được diễn tả như sau:
1.5.1.2 Ngữ nghĩa
Công thức LTL thể hiện cho các thuộc tính của đường - path (hay truy vết của chúng) Tức là một đường có thể thõa mãn một công thức LTL hoặc không
Ngữ nghĩa của công thức LTL φ được định nghĩa như là một ngôn ngữ
công thức LTL liên kết các thuộc tính LT đơn Ngữ nghĩa của nó được mở rộng
để giải thích các đường và các trạng thái của hệ thống truyền
Định nghĩa 1.2: Ngữ nghĩa của LTL
Giả sử φ là một công thức LTL trên AP Thuộc tính Linear - Time có thể được kết luận bởi φ là:
Ở đây |= (2 AP) LTL là quan hệ nhỏ nhất thỏa mãn:
Trang 17Với = A 0 A 1 A 2 … (2 AP), [j…] = A j A j+1 A j+2 … được gọi là hậu tố của
toán tử □, ◊, □◊ và ◊□ như sau:
1.5.1.3 Sự tương đương của công thức LTL
Đối với bất kì kiểu logic nào, một sự tách biệt rõ ràng giữa cú pháp và ngữ nghĩa là cần thiết Mặt khác, hai công thức được xem như là tương đương khi
chúng đều có cùng giá trị chân lý Ví dụ như là: hai công thức a và a, mặc
dù khác nhau về cú pháp nhưng lại tương đương nhau
Định nghĩa 1.3: Sự tương đương của công thức
Hai công thức LTL φ 1 , φ 2 được gọi là tương đương được viết là φ = φ 2 nếu
Có thể sử dụng một số luật để thuận thiện cho việc diễn đạt thuộc tính dưới dạng LTL
Bổ đề 1.1: Giải pháp tối thiểu của sự mở rộng các luật
Cho hai công thức LTL φ và , Words(φ ∪ ) là thuộc tính LT tối thiểu,
P (2 AP ) khi đó:
Ngoài ra, Words(φ ∪ ) phù hợp với tập:
1.5.1.4 Toán tử Weak Until – W
Toán tử Weak Until φW (φ ∪ ) □φ dường như ngược lại với toán
tử until Toán tử φ ∪ không yêu cầu φ phải được thõa mãn
Toán tử Until ∪ và toán tử Weak Untill W là đối ngẫu:
(φ ∪ ) (φ ) W (φ )
(φ W ) (φ ) ∪ (φ )
Trang 181.5.2 Các thuộc tính cần kiểm chứng
1.5.2.1 Thuộc tính an toàn (Safety)
Tính an toàn của một chương trình đảm bảo rằng sẽ không bao giờ xảy ra
tình huống xấu trong chương trình (“something bad never happen”)
Tính an toàn có thể được biểu diễn bằng LTL như sau:
G ϕ trong LTL
Trong đó ϕ là một biểu thức logic
Ví dụ của tính an toàn:
Nhiệt độ của phản ứng không bao giờ quá 100 độ C
Bất kì lúc nào chìa khóa xe chưa vặn tới vị trí khởi động, xe sẽ không nổ máy
Thuộc tính an toàn thể hiện trong LTL: Cho công thức LTL và cho = (s 0 ,
với mọi s j trong mà j ≥ i
Công thức □A được gọi là thuộc tính an toàn bởi nó đặc tả sự tính toán an toàn mà không bao giờ xảy ra trường hợp xấu “bad”, hay tương tự thế mà luôn xảy ra trường hợp tốt “good” Có thể vẽ sơ đồ thể hiện sự tính toán, mỗi trạng thái s i được gán nhãn A nếu A đúng với s i , và gán A nếu A sai với s i Nếu sơ đồ
được mở rộng với mọi trạng thái được gán nhãn A thì □A đúng với s 0:
1.5.2.2 Thuộc tính sống (Liveness)
Thuộc tính liveness của một chương trình đảm bảo rằng nó có thể thực thi
được một chức năng tốt“good” nào đó đã đặt ra (“something good will happen
eventually”)
Ví dụ 1.2:
Khi chìa khóa xe vặn tới vị trí khởi động, xe sẽ nổ máy
Bóng đèn sẽ chuyển sang màu xanh
Thuộc tính liveness thể hiện trong LTL: Cho công thức LTL A và = (s 0 , s 1 ,
với một vài s j trong mà j ≥ i
Công thức ◊A được gọi là thuộc tính liveness bởi nó đặc tả trong sự tính toán luôn có một vài trường hợp tốt “good”
1.5.2.3 Thuộc tính công bằng (Fairness)
Tính công bằng đảm bảo rằng nếu một sự kiện nào đó ở trạng thái sẵn sàng được thực thi thì đến một lúc nào đó nó sẽ được thực thi
…
Trang 19Công bằng yếu (Weak Fairness) đảm bảo nếu một sự kiện được kích hoạt liên tục thì sẽ xảy ra vô hạn lần
Công bằng mạnh (Strong Fairness) đảm bảo nếu một sự kiện được kích hoạt vô hạn lần thì sẽ xảy ra vô hạn lần
Một ví dụ cho tính công bằng trong một hệ thống truyền – nhận là khi một gói tin được gửi đi thì đến một lúc nào đó nó sẽ đến được đích
1.6 Máy trạng thái hữu hạn
1.6.1 Định nghĩa máy trạng thái hữu hạn
Có rất nhiều mô hình được sử dụng trong kiểm chứng phần mềm, trong đó
có mô hình máy hữu hạn trạng thái – Finite State Machines (FSM)
Máy hữu hạn trạng thái là một Automata đơn giản có thể được định nghĩa như sau:
Máy hữu hạn trạng thái là một bộ M = < I, S, O, s o , δ, λ> Trong đó I: Tập các yếu tố đầu vào;
S: Tập các trạng thái;
O: Tập thông tin đầu ra;
s 0: Trạng thái ban đầu;
δ: S x I → S là hàm chuyển trạng thái;
λ: S x I → O là hàm thông tin đầu ra
Ví dụ 1.3: Máy trạng thái hữu hạn được thể hiện dạng đồ thị:
Hình 1.3: Ví dụ máy hữu hạn trạng thái dạng đồ thị
1/1 0/0
0/0
Trang 20λ = {λ(S0,0) = 0, λ(S0,1) = 0, λ(S1,0) = 0, λ(S1,1) = 0, λ(S2,0) = 0, λ(S2,1)
= 0, λ(S3,0) = 0, λ(S3,1) = 0}
Mô hình máy hữu hạn trạng thái FSM được sử dụng để mô tả hoạt động của nhiều hệ thống trong thực tế
1.6.2 Các máy trạng thái hữu hạn trao đổi thông tin
Các máy trạng thái hữu hạn trao đổi thông tin với nhau qua việc truyền các thông báo một cách đồng bộ Trong quá trình truyền giữa các nhãn cần có sự
đồng bộ hóa giữa thông điệp gửi m (!m) và thông điệp nhận (?m) Việc truyền
đồng bộ chỉ được thực hiện khi thông điệp gửi và thông điệp nhận là đồng thời
và tương ứng [5]
Hình 1.4: Truyền thông điệp đồng bộ hóa (!m, ?m), (?m, !m) [5]
Trong quá trình đồng bộ hóa, các thông điệp không được truyền ngay khi gửi Do đó các kênh truyền được xem như bộ đệm giới hạn dạng FIFO (First In First Out) [5]
Hình 1.5: Đồng bộ hóa thông điệp [5]
Sending m Receiving m
Trang 21CHƯƠNG 2: GIỚI THIỆU VỀ SPIN VÀ PROMELA
Để kiểm chứng mô hình phần mềm sử dụng kỹ thuật kiểm duyệt mô hình cần có những công cụ hỗ trợ, cụ thể là Spin Để có thể làm việc được với Spin chúng ta phải xây dựng mô hình hệ thống bằng ngôn ngữ mô hình hóa Promela Trong chương này sẽ trình bày về những khái niệm cơ bản của ngôn ngữ mô hình hóa Promela, công cụ kiểm chứng Spin, giao diện người dùng Xspin, cách kiểm chứng một chương trình Promela trong Spin, và giới thiệu về logic thời gian tuyến tính để biểu diễn tính chất cần kiểm chứng và các thuộc tính tuyến tính
2.1 Ngôn ngữ Promela
Promela là ngôn ngữ mô hình hóa dùng để mô tả hệ thống đồng thời [3] Chẳng hạn như hệ thống điện thoại, chương trình giao tiếp đa luồng, giao thức mạng,… Nó là ngôn ngữ không tất định, có cú pháp và ngữ nghĩa tương tự ngôn ngữ C [9]
2.1.1 Cấu trúc chương trình Promela
Cấu trúc cơ bản của một trương trình Promela [1]:
Các khai báo kiểu và khai báo biến;
Khai báo tiến trình;
Tiến trình init
Chẳng hạn, cấu trúc chương trình Promela
/*Các khai báo kiểu và biến*/
mtype ={ABC, DEF}
/*Tiến trình init*/
/*Tạo tiến trình*/
… }
Một chương trình Promela chứa các tiến trình, các tiến trình được khai báo
và có thể có tham số hay không, nhưng luôn phải có cặp ([danh sách tham số])
Trang 22theo sau tên tiến trình Các lệnh trong tiến trình được viết trong cặp {các lệnh trong tiến trình}, lời chú thích được đặt trong cặp /*lời chú thích*/
cơ bản được mặc định giá trị khởi tạo là 0 Cũng như trong C, 0 được xem là sai, các giá trị khác 0 được xem là đúng Một biến trong Promela có thể là toàn cục hay cục bộ
Ví dụ 2.2: khai báo biến trong Promela
byte count, total = 4;
Trong ví dụ 2.2 biến count và total có kiểu byte, biến total được khởi tạo
giá trị là 4
2.1.3 Kiểu dữ liệu
2.1.3.1 Các kiểu dữ liệu cơ bản trong Promela
Các kiểu dữ liệu cơ bản trong Promela được liệt kê trong bảng sau:
Bảng 2.1: Các kiểu dữ liệu cơ bản trong Promela [1]
bit or bool 1 0 1
Trang 23short 16 -215-1 215-1 int 32 -231-1 231-1
2.1.3.2 Kiểu dữ liệu có cấu trúc
Kiểu cấu trúc (bản ghi)
Định nghĩa kiểu: Để định nghĩa một kiểu mới, ta sử dụng từ khóa typedef Với typedef ta có thể định nghĩa được dữ liệu kiểu cấu trúc tương tự như C Và
giải quyết được vấn đề mảng 2 chiều khi Promela không hỗ trợ mảng n chiều
Ví dụ 2.4: Sử dụng typedef để định nghĩa kiểu message
Trong ví dụ 2.5 định nghĩa kiểu cấu trúc
Biến cấu trúc trong Promela được truy cập giống C, chẳng hạn với kiểu cấu
trúc được khai báo trong ví dụ 2.5, khai báo biến message có kiểu msg, và sau
đó truy cập tới từng phần tử trong cấu trúc qua biến cấu trúc message:
msg message;
message.data[0];
Kiểu liệt kê
Kiểu liệt kê là tập các ký hiệu hằng
Trang 24Ví dụ 2.6: Khai báo kiểu liệt kê
mtype = {line_clear, train_online, line_blocking};
Dữ liệu kiểu kênh
Trong Promela, với dữ liệu kiểu kênh có 2 toán tử ! (gửi) và ? (nhận)
Cấu trúc khai báo kênh:
chan ch = [dung lượng] of {kiểu_dữ_liệu_1, …, kiểu_dữ_liệu_n};
Ví dụ 2.7:
chan in_data = [8] of {byte};
Trong ví dụ 2.7 khai báo kênh in_data có thể lưu trữ 8 thông điệp kiểu byte
Ngoài ra còn có thể truyền nhiều thông tin
Ví dụ 2.8:
chan out_data = [8] of {byte, bool}
Kênh out_data trong ví dụ 2.8 có thể lưu trữ 8 thông điệp, các thông điệp
có thể là kiểu byte hay kiểu bool
Truyền dữ liệu kiểu kênh:
Gửi thông điệp
Tên_tiến_trình ! biểu_thức_1, …, biểu_thức_n;
Ví dụ 2.9:
int_data ! x+1, true, in_data;
Lệnh gửi được thực hiện khi kênh còn có thể chứa thông điệp (kênh không đầy)
Nhận thông điệp
Tên_biến_kênh ? biến_1, …, biến_n;
Ví dụ 2.10:
out_data ? value1, value2;
Lệnh nhận được thực hiện khi có thông điệp được gửi qua kênh (kênh không rỗng)
Các phép toán kiểm tra điều kiện kênh:
o Để biết độ dài của kênh sử dụng toán tử len: len(in_data)
o Kiểm tra kênh rỗng, đầy để cho phép thông điệp được nhận hay gửi:
Kiểm tra rỗng: empty(in_data)
Kiểm tra đầy: full(out_data)
Các biểu thức trong lệnh gửi thông điệp sẽ tính toán giá trị thu được
là thông điệp truyền trên kênh, lệnh nhận thông điệp được thực thi sau khi nó gán các giá trị này cho các biến của nó
Trang 25 Trong Promela có hai loại kênh là Rendezvous channels và
Buffered channels Rendezvous channels là kênh được khai báo với
dung lượng là 0 Việc gửi và nhận thông điệp của thành phần gửi và thành phần nhận là đồng bộ Tức thông điệp được gửi đi sẽ được nhận ngay lập tức Với loại kênh này tiến trình gửi sẽ bị chặn đến khi lệnh nhận trong tiến trình nhận được thực thi Nếu trong một tiến trình có một lệnh gửi (hay một lệnh nhận) được khởi tạo mà không có lệnh nhận (hay lệnh gửi) nào tương ứng về kiểu thông
điệp thì tiến trình đõ sẽ bị khóa Buffered channels là kênh được
khai báo với một dung lượng là hằng số nguyên Khi sử dụng dạng kênh này thì thông điệp sẽ vào ra qua kênh theo dạng FIFO – First
in first out Khi đó các tiến trình gửi và nhận sẽ hoạt động không đồng bộ
Ví dụ 2.11: Ví dụ hai tiến trình Client0 và Client1, gửi yêu cầu đến tiến trình khác là Server thông qua kênh request có dung lượng bằng 0
byte client;
end:
do :: request ? client ->
od }
}
request ! 1 }
2.1.3.3 Kiểu mtype
Giả sử ta muốn dùng một kí hiệu cho một số, ta có thể sử dụng macro
define khai báo tại đầu chương trình – tương tự như ngôn ngữ C:
Trang 26mtype light = green;
active proctype P(){
do
::if
:: light == red -> light = green
:: light == yellow -> light = red
:: light == green -> light = yellow
fi;
printf("The light is now %e\n", light)
od
}
Một vài kết quả của lệnh printf là:
The light is now yellow
The light is now red
The light is now green
2.1.4 Định danh, hằng, và biểu thức
Định danh có thể là một chữ cái, một ký tự, một dấu chấm hay dấu gạch dưới
Hằng số là một chuỗi ký tự đại diện cho số nguyên, số thập phân,…
Ví dụ 2.13: định nghĩa hằng Max có giá trị 999
Trang 27Cú pháp khai báo tiến trình:
proctype name_process (/*danh sách tham số hình thức*/)
Một tiến trình init có dạng:
init {/* Các khai báo biến cục bộ và các câu lệnh*/}
Ví dụ 2.14: chương trình Promela đơn giản nhất
init {skip;}
/*Trong tiến trình trên không có biểu thức nào*/
Một tiến trình process được khai báo qua từ khóa proctype, việc cài đặt và thực thi tiến trình được thực hiện qua tiến trình init
Ví dụ 2.15:
proctype hello() {
printf(“Hello”);
} proctype word() {
printf(“Word”);
Trang 28} init {
Nhiều trường hợp việc khai báo tiến trình sử dụng từ khóa active giống như khai báo proctye bằng cách dùng mảng có hậu tố tùy chọn theo sau từ khóa
Trang 292.1.6 Run và atomic
2.1.6.1 Run và tiến trình init()
Cách khởi tạo tiến trình trong tiến trình init là dùng toán tử run, khi tiến trình được khai báo mà không có từ khóa active
Tiến trình init() luôn được khởi tạo đầu tiên nên luôn có pid = 0
Ví dụ 2.18:
proctype A() {
… } proctype B() {
… } init {
run A();
run B();
}
2.1.6.2 Atomic
Các lệnh được đặt trong atomic { } sẽ được thực hiện như một lệnh độc lập
và không bị các lệnh khác ngoài nó chen vào Việc sử dụng atomic nhằm giảm
sự phức tạp của mô hình cần kiểm duyệt
Đoạn mã trong ví dụ 2.19 tương đương với n = n+1;
Có thể sử dụng atomic để kết hợp các câu lệnh giữa các tiến trình
Ví dụ 2.20:
chan ch = [0] of {init}
active proctype A() {atomic {
C; ch!1; D }
} active proctype B() {atomic {
} }
Trang 30Trong ví dụ 2.20 sau khi khối lệnh C trong tiến trình A được thực thi, giá trị
1 (kiểu int) được gửi cho kênh ch có kiểu gặp (lệnh ch!1; được thực hiện), tiến trình B nhận dữ liệu trên kênh (ch?1) và khối lệnh E được thực thi, khi khối lệnh
E kết thúc, việc thực thi sẽ tự động chuyển về tiến trình A và thực thi khối lệnh
D
Atomic được sử dụng để khởi tạo một số các tiến trình và đảm bảo không
một tiến trình nào được thực hiện cho tới khi tất cả các tiến trình trong nó đều được thực hiện
Ví dụ 2.21: khởi tạo hai tiến trình P, Q:
proctype P() {
…
} proctype Q() {
…
} init {
Ví dụ 2.22:
proctype P() {
… } proctype Q() {
… } init {
atomic {
run P();
run Q();
} }
Trang 312.1.7 Cấu trúc điều khiển
printf ("d = %d: no real roots\n", d) :: d == 0 ->
printf ("d = %d: dup licate real roots\n", d) :: d > 0 ->
printf ("d = %d: two real roots\n", d)
fi }
Trong ví dụ 2.23 sau khi tính được giá trị của d, cấu trúc if sẽ kiểm tra giá trị của d theo từng trường hợp, và trong ví dụ này sẽ in ra kết quả là 0
int a = x, b = y;
Trang 32do
:: a > b -> a = a - b :: b > a -> b = b - a :: a == b -> break
Lệnh goto nhảy đến một đoạn chương trình sau một nhãn, tên nhãn được
đặt trước dấu hai chấm
2.2.1 Kiểm chứng chương trình trong Spin
2.2.1.1 Đặc trưng của SPIN
Spin (Simple Promela Interpreter) là một công cụ kiểm chứng, nó hỗ trỡ ngôn ngữ đặc tả hệ thống Promela Spin được dùng để theo dõi những lỗi logic ở trong những bản thiết kế của hệ thống phân tán như hệ điều hành, giao thức truyền thông dữ liệu, thuật toán song song, giao thức báo hiệu tàu điện, Ta có thể sử dụng Spin mà không cần phải dựng lên mô hình dưới dạng đồ thị trạng thái [5]
Spin hỗ trợ kiểm chứng mọi thuộc tính yêu cầu có thể biểu diễn dưới dạng LTL (Linear Temporal Logic – Logic thời gian tuyến tính), hoặc cũng có thể sử dụng các khẳng định – assertion để đặc tả một số thuộc tính cần kiểm chứng Ngôn ngữ đặc tả Promela được sử dụng để diễn tả mô hình hệ thống và thuộc tính của nó để kiểm chứng mô hình
Spin có thể mô phỏng sự thực thi của hệ thống
Việc sử dụng Spin rất đơn giản, hiệu quả cao, và nó phù hợp để kiểm chứng hệ thống phân tán
Spin không hỗ trợ kiểm chứng hệ thống vô hạn trạng thái
Trang 332.2.1.2 Mô hình hệ thống trong SPIN
Các hệ thống được mô hình hóa trong Spin như là một tập các tiến trình (mạng các Automata), được chạy song song theo chế độ đan xen và giao tiếp với nhau qua các thông điệp hay qua chia sẻ các biến
Hình 2.1: mô hình của hệ thống trong Spin [5]
2.2.1.3 Cấu trúc của Spin
Cấu trúc cơ bản của Spin được thể hiện trong hình 2.2 Luồng công việc bắt đầu từ việc đặc tả mô hình ở mức cao của hệ thống hiện thời, qua giao diện Front-End của Xspin (giao diện đồ họa người dùng của Spin), sau đó kiểm tra lỗi cú pháp, thực hiện mô phỏng tương tác cho đến khi người dùng nhận được sự tin cậy cơ bản mô hình thuộc tính mong đợi Một chương trình Promel đúng đắn
có thể yêu cầu được tạo từ một công thức được đặc tả trong logic thời gian tuyến tính (LTL) Sau đó Spin được sử dụng để tạo một chương trình xác minh tối ưu Chương trình xác minh này được biên dịch với thời gian biên dịch có thể được chọn trước, và sau đó thực hiện xác minh chính nó Nếu bất kỳ phản ví dụ nào thỏa mãn yêu cầu tính đúng đắn được phát hiện thì chúng có thể được đưa trở lại
để mô phỏng trong Spin Việc mô phỏng có thể được kiểm tra chi tiết để xác định nguyên nhân [3]
Shared Variables (shared memory)