Nhưng trong quá trình kiểm chứng mô hình để cho việc kiểm chứng là thực hiện được, thì một số các tính chất, đặc tả chi tiết của chương trình đã bị loại bỏ.. Đề tài thực hiện việc kiểm c
Trang 1TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
NGÔ THỊ NGA
KẾT HỢP PHƯƠNG PHÁP KIỂM CHỨNG MÔ HÌNH VÀ CÁC KỸ THUẬT KIỂM THỬ PHẦN MỀM LÀM TĂNG ĐỘ
TIN CẬY CỦA HỆ THỐNG PHẦN MỀM
LUẬN VĂN THẠC SĨ CÔNG NGHỆ THÔNG TIN
Hà Nội - 2014
Trang 2ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
NGÔ THỊ NGA
KẾT HỢP PHƯƠNG PHÁP KIỂM CHỨNG MÔ HÌNH VÀ CÁC KỸ THUẬT KIỂM THỬ PHẦN MỀM LÀM TĂNG ĐỘ
TIN CẬY CỦA HỆ THỐNG PHẦN MỀM
Ngành: Công nghệ thông tin
Chuyên ngành: Kỹ thuật phần mềm
Mã số: 60480103
LUẬN VĂN THẠC SĨ CÔNG NGHỆ THÔNG TIN
NGƯỜI HƯỚNG DẪN KHOA HỌC: TS ĐẶNG VĂN HƯNG
Hà Nội – 2014
Trang 3Lời cam đoan
Tôi xin cam đoan rằng luận văn cao học này do chính tôi thực hiện Những kết quả được tổng hợp và nghiên cứu từ các tài liệu tham khảo sử dụng trong luận văn này được thu thập từ các nguồn thông tin được công bố trên các sách báo, tạp chí khoa học chuyên ngành đáng tin cậy và kiến thức, kinh nghiệm của bản thân Tôi hoàn toàn chịu trách nhiệm trước nhà trường về sự cam đoan này
Hà Nội, ngày 11 tháng 06 năm 2014
Ngô Thị Nga
Trang 4Lời cảm ơn
Em xin gửi lời cảm ơn chân thành tới các thầy cô giảng viên trong bộ môn Kỹ thuật phần mềm, khoa Công nghệ thông tin, trường Đại học Công nghệ đã giảng dạy
và truyền đạt những kiến thức, kinh nghiệm cho em trong thời gian qua
Em xin được gửi lời cảm ơn sâu sắc nhất tới thầy giáo TS Đặng Văn Hưng, thầy
đã giúp đỡ, hướng dẫn và chỉ bảo cho em trong suốt quá trình học tập và thực hiện luận văn
Bên cạnh những kết quả mà em đạt được, em cũng không tránh khỏi những thiếu sót trong quá trình thực hiện luận văn, em kính mong các thầy cô thông cảm cho em
Sự góp ý, giúp đỡ của thầy cô sẽ là những kinh nghiệm quý báu cho quá trình học tập
và làm việc của em sau này
Em kính chúc thầy cô luôn mạnh khỏe, công tác tốt và đạt được nhiều thành công trong cuộc sống cũng như trong sự nghiệp trồng người của mình
Hà Nội, ngày 11 tháng 06 năm 2014
Ngô Thị Nga
Trang 5Mục lục
Lời cam đoan 2
Lời cảm ơn 3
Mục lục 4
Danh mục hình vẽ 6
Danh mục bảng biểu 7
Chương 1 Giới thiệu 8
1.1 Đặt vấn đề 8
1.2 Nội dung nghiên cứu 8
1.3 Cấu trúc luận văn 9
Chương 2 Tổng quan về kiểm thử phần mềm 10
2.1 Tổng quan về kiểm thử phần mềm 10
2.1.1 Chất lượng phần mềm 10
2.1.2 Kiểm thử và vai trò của kiểm thử 10
2.1.3 Các mục tiêu của kiểm thử 11
2.1.4 Ca kiểm thử 12
2.1.5 Các hoạt động kiểm thử 12
2.1.6 Các mức độ kiểm thử 13
2.1.7 Các giới hạn của kiểm thử 14
2.2 Các kỹ thuật kiểm thử phần mềm 14
2.2.1 Kỹ thuật phân lớp tương đương 15
2.2.2 Phương pháp kiểm thử đột biến (mutation testing) 15
Chương 3 Kiểm chứng mô hình 19
3.1 Khái niệm kiểm chứng mô hình 19
3.2 Quy trình kiểm chứng mô hình 21
3.3 Ưu và nhược điểm của kiểm chứng mô hình 23
3.3.1 Ưu điểm của kiểm chứng mô hình 23
3.3.2 Nhược điểm của kiểm chứng mô hình 24
3.4 Logic thời gian tuyến tính (Linear Temporal Logic - LTL) 25
3.4.1 Trạng thái thời gian tuyến tính (Linear-Time Behavior) 25
3.4.2 Thuộc tính thời gian tuyến tính 27
3.4.3 Các thuộc tính an toàn (safety properties) 28
3.5 Các công cụ kiểm chứng mô hình 33
Chương 4 Ngôn ngữ Promela và công cụ kiểm chứng mô hình SPIN 35
4.1 Ngôn ngữ Promela 35
4.1.1 Kiểu dữ liệu, toán tử và câu lệnh 35
Trang 64.1.2 Dữ liệu và cấu trúc chương trình 37
4.1.3 Cấu trúc kiểu kênh thông điệp và tiến trình 39
4.1.4 Một số hàm đặc biệt 42
4.1.5 Biểu diễn các thuộc tính thời gian tuyến tính 44
4.2 Kiểm chứng bằng công cụ SPIN 46
4.2.1 Công cụ SPIN 46
4.2.2 Kiểm chứng một chương trình bằng công cụ SPIN 48
Chương 5 Kết hợp kiểm chứng mô hình và các kỹ thuật kiểm thử phần mềm 51
5.1 Ý nghĩa 51
5.2 Mô hình đề xuất 51
5.3 Tính đúng đắn của cách tiếp cận 56
5.4 Ưu điểm và nhược điểm của cách tiếp cận 57
Chương 6 Thực nghiệm 58
6.1 Mô tả bài toán thực nghiệm – bài toán ATM 58
6.2 Xây dựng mô hình và kiểm chứng 59
6.2.1 Máy trạng thái hữu hạn mở rộng EFSM 59
6.2.2 Mô hình hóa hệ thống bằng ngôn ngữ Promela 60
6.2.3 Hình thức hóa và kiểm chứng các yêu cầu hệ thống 63
6.3 Biến đổi hệ thống bằng kỹ thuật kiểm thử đột biến 65
6.3.1 Biến đổi mô hình hệ thống 66
6.3.2 Biến đổi yêu cầu đặc tả của hệ thống 67
6.4 Kết luận 69
Kết luận 71
1 Kết quả của luận văn 71
2 Hướng nghiên cứu tiếp theo 71
Tài liệu tham khảo 72
Phụ lục i
Trang 7Danh mục hình vẽ
Hình 2.1 Mô hình chữ V trong phát triển phần mềm 13
Hình 2.2 Chương trình kiểm tra ba cạnh của tam giác 16
Hình 3.1 Mối liên hệ giữa kiểm chứng hình thức, kiểm chứng mô hình và khái niệm hình thức 19
Hình 3.2 Cách tiếp cận kiểm chứng mô hình 21
Hình 4.1 Các toán tử trong ngôn ngữ Promela 36
Hình 4.2 Ví dụ về hoạt động của kênh 39
Hình 4.3 Ví dụ về kênh gặp 40
Hình 4.4 Sơ đồ gửi nhận thông điệp trên kênh gặp 40
Hình 4.5 Sơ đồ gửi nhận thông điệp trong kênh đệm 41
Hình 4.6 Giao diện màn hình Edit trên iSPIN 46
Hình 4.7 Giao diện khung làm việc Simulate/ Replay 47
Hình 4.8 Giao diện khung làm việc Verification 47
Hình 4.9 Kiến trúc của SPIN 48
Hình 4.10 Ví dụ về một chương trình có lỗi 49
Hình 4.11 Kiểm chứng chương trình trong hình 4.10 49
Hình 4.12 Giả lập có hướng dẫn với Trial được tạo ra ở hình 4.9 50
Hình 5.1 Kiểm thử đột biến hướng mô hình 52
Hình 5.2 Cách tiếp cận kiểm chứng mô hình kết hợp với kiểm thử đột biến 53
Hình 6.1 EFSM của máy rút tiền tự động 60
Hình 6.2 Lược đồ truyền thông điệp trong máy ATM 61
Hình 6.3 Các thông điệp trong máy ATM 61
Hình 6.4 Các kênh thông điệp trong máy ATM 62
Hình 6.5 Hàm init khởi tạo các tiến trình 62
Hình 6.6 Mã lệnh Promela của tiến trình Customer 63
Hình 6.7 Kết quả kiểm chứng với yêu cầu đặc tả thứ nhất 65
Hình 6.8 Kết quả kiểm chứng với yêu cầu đặc tả thứ hai 65
Hình 6.9 Kết quả kiểm chứng mô hình với đặc tả sai Mutant 6 68
Hình 6.10 Kết quả kiểm chứng mô hình với đặc tả sai Mutant 7 69
Trang 8Danh mục bảng biểu
Bảng 3.1 Các toán tử trong LTL 32
Bảng 3.2 Các toán tử thời gian trong LTL 32
Bảng 3.3 Bảng chân giá trị 33
Bảng 4.1 Kiểu dữ liệu số của Promela 35
Bảng 5.1 Các toán tử đột biến trong ngôn ngữ Promela 55
Bảng 5.2 Mối quan hệ giữa đặc tả và mô hình hệ thống 57
Trang 9Chương 1 Giới thiệu 1.1 Đặt vấn đề
Hàng ngày, mỗi chúng ta đều tiếp xúc với hàng trăm thiết bị điện tử, đồ gia dụng, máy vi tính ẩn chứa trong đó là những hệ thống máy tính và các chương trình ứng dụng phần mềm Máy vi tính và các hệ thống thông tin đã đi sâu vào đời sống của mỗi người Bất cứ một sai sót nào của các thiết bị này đều khó mà chấp nhận được, những sai lầm này đều phải trả giá bằng sinh mạng con người, bằng vật chất Theo [3], ngày 04/06/1996, tàu vũ trụ Ariane-5 đã nổ tung ngay sau khi khởi động được 36 giây
do lỗi chuyển đổi một số dạng dấu phẩy động 64-bit thành giá trị nguyên dương 16-bit Theo [13], tháng 2-2014 Toyota đã phải thu hồi 1,9 triệu xe ôtô Prius trên toàn cầu vì lỗi lập trình hệ thống lai phối hợp hai hệ thống xăng và điện Vì vậy độ tin cậy của các
hệ thống máy tính là điều quan trọng nhất trong quá trình phát triển phần mềm
Các kỹ thuật kiểm thử cho chúng ta các chứng cứ về độ tin cậy của hệ thống Vì các kỹ thuật này được thực hiện trên các mã lệnh của chương trình và tìm ra các lỗi phân tích, lỗi thiết kế và lỗi về đảm bảo tính dễ dùng của chương trình
Kiểm chứng mô hình (Model checking) là một kỹ thuật tự động kiểm tra tính đúng đắn của một mô hình được sinh ra từ hệ thống Nếu mô hình thoả mãn được các đặc tả của hệ thống thì ta nói mô hình đó đúng đắn Nếu mô hình không thoả mãn các đặc tả của hệ thống thì ta nói mô hình đó sai, và các phản ví dụ sẽ được tạo ra để chứng minh mô hình sai Kiểm chứng mô hình được thực hiện tự động bởi các công cụ kiểm chứng (Model checker), và một trong những công cụ hiệu quả nhất là SPIN Kiểm chứng mô hình la thực hiện kiểm tra bằng cách vét cạn các khả năng có thể xảy
ra của mô hình trừu tượng Nhưng trong quá trình kiểm chứng mô hình để cho việc kiểm chứng là thực hiện được, thì một số các tính chất, đặc tả chi tiết của chương trình
đã bị loại bỏ Vì vậy, dù một mô hình hệ thống đáp ứng được đặc tả của hệ thống, thì
hệ thống thật chưa chắc đã đáp ứng được hết các đặc tả, mà ta cần tiến hành kiểm thử
kỹ thuật kiểm thử
1.2 Nội dung nghiên cứu
Luận văn tập trung nghiên cứu và khảo sát tổng quan về kiểm thử phần mềm và các kỹ thuật kiểm thử phần mềm; kỹ thuật kiểm chứng mô hình, các ưu, nhược điểm của nó và các thuộc tính thời gian; luận văn cũng nghiên cứu về ngôn ngữ Promela và
sử dụng công cụ SPIN để kiểm chứng mô hình Từ hiểu biết về kiểm thử phần mềm và
Trang 10kiểm chứng mô hình, luận văn đưa ra phương pháp kết hợp hai kỹ thuật này Đề tài thực hiện việc kiểm chứng trên mô hình bởi công cụ SPIN và sau đó tiến hành thẩm định chương trình bằng các kỹ thuật kiểm thử để làm tăng tính tin cậy của hệ thống
1.3 Cấu trúc luận văn
Luận văn có cấu trúc như sau: Chương 2 trình bày kiến thức tổng quan về kiểm thử phần mềm, và các kỹ thuật kiểm thử phần mềm Chương 3 giới thiệu các khái niệm về kiểm chứng mô hình, ưu nhược điểm của kiểm chứng mô hình, logic thời gian, các thuộc tính thời gian, và logic thời gian tuyến tính Chương 4 giới thiệu về ngôn ngữ Promela, các kiểu dữ liệu, các quy tắc trong lập trình, cách biểu diễn các thuộc tính thời gian tuyến tính và công cụ kiểm chứng SPIN Chương 5 đề xuất mô hình kết hợp kiểm chứng mô hình và các kỹ thuật kiểm thử phần mềm Việc ứng dụng công cụ kiểm chứng SPIN và các kỹ thuật kiểm thử để tăng tính tin cậy của hệ thống phần mềm sẽ được trình bày trong chương 6 Cuối cùng là kết luận về quá trình nghiên cứu, đưa ra các kết quả đạt được và hướng nghiên cứu tiếp theo
Trang 11Chương 2 Tổng quan về kiểm thử phần mềm
Chương 2 trình bày tổng quan về kiểm thử phần mềm và các phương pháp kiểm thử phần mềm
2.1 Tổng quan về kiểm thử phần mềm
2.1.1 Chất lượng phần mềm
Trước khi nói về kiểm thử phần mềm, chúng ta cần hiểu rõ khái niệm “chất lượng phần mềm.” Theo [9], chất lượng phần mềm được đánh giá theo năm góc nhìn khác nhau như sau:
Góc nhìn tiên nhiệm (Transcendental View): Chất lượng là một thứ gì đó dễ dàng thừa nhận nhưng khó để định nghĩa Góc nhìn tiên nhiệm không đặc tả riêng rẽ được chất lượng phần mềm nhưng có thể ứng dụng vào những phần phức tạp khác nhau trong cuộc sống hàng ngày
Góc nhìn người dùng (User View): Chất lượng được cho là phải phù hợp với mục đích Theo góc nhìn này thì khi đánh giá chất lượng của một sản phẩm, chúng ta phải đặt ra và trả lời cho một câu hỏi quan trọng là “Liệu sản phẩm có thỏa mãn yêu cầu và mong muốn của người dùng hay không?”
Góc nhìn sản xuất (Manufacturing View): Ở đây, chất lượng được hiểu là sự đáp ứng được đặc tả Chất lượng ở mức độ sản phẩm được xác định bởi việc là sản phẩm có gặp được đặc tả của nó hay không
Góc nhìn sản phẩm (Product View): Trong trường hợp này, chất lượng được xem như là một đặc tính vốn có của sản phẩm
Góc nhìn dựa vào giá trị (Value-Based View): Chất lượng, theo khía cạnh này phụ thuộc vào tổng giá trị mà khách hàng vui lòng trả cho nó
Khái niệm về chất lượng phần mềm và các nỗ lực để hiểu được nó theo một cách
có thể định lượng được đã bắt đầu được nghiên cứu từ những năm 1970 Trong tài liệu
về tiêu chuẩn ISO 9126 thì chất lượng phần mềm được định nghĩa trên sáu thuộc tính là: tính năng, tính đáp ứng, tính dễ dùng, tính hiệu quả, tính có thể bảo trì được và tính khả chuyển Một ràng buộc về chất lượng là một thuộc tính của một yếu tố chất lượng liên quan đến quá trình phát triển phần mềm
2.1.2 Kiểm thử và vai trò của kiểm thử
Kiểm thử phần mềm đóng một vai trò quan trọng trong việc hoàn thành và đánh giá chất lượng của một sản phẩm phần mềm Theo [9], chúng ta cải tiến chất lượng của sản phẩm bằng việc lặp đi lặp lại quá trình kiểm thử - tìm lỗi – sửa lỗi trong suốt quá trình phát triển Mặt khác, chúng ta đánh giá cách hệ thống có thể hoạt động đúng khi chúng ta thực hiện kiểm thử ở mức hệ thống trước khi bàn giao sản phẩm Theo Friedman và Voas đã mô tả thì kiểm thử phần mềm là một quá trình thẩm định cho việc đánh giá và cải thiện chất lượng phần mềm
Trang 12Thông thường, các hoạt động đánh giá phần mềm được chia làm hai loại là: phân
tích tĩnh (static analysis) và phân tích động (dynamic analysis) Phân tích tĩnh là việc
đánh giá chương trình mà không cần thực thi trên các mã lệnh của chương trình, nó có
thể là các hoạt động xem xét (review) lại các tài liệu đặc tả, tài liệu thiết kế, tài liệu ca kiểm thử, hoặc là thanh tra mã nguồn (code inspection), … Phân tích động là việc
đánh giá chương trình mà cần thực thi trên các mã lệnh của chương trình, trong đó có
kỹ thuật kiểm thử hộp đen và hộp trắng
Bằng việc thực hiện phân tích tĩnh và phân tích động thì người kiểm thử viên mong muốn tìm được nhiều lỗi nhất có thể, để các lỗi này được sửa trong các giai đoạn sớm của quy trình phát triển phần mềm
Xác minh (Verification) và thẩm định (Validation) là những công việc xuyên
suốt trong quá trình phát triển phần mềm, chứ không phải khi đã có mã nguồn của chương trình Xác minh là sự kiểm tra xem phần mềm có thỏa mãn được yêu cầu đặc
tả của hệ thống không? Nó trả lời cho câu hỏi “Hệ thống đã được xây dựng đúng theo đặc tả chưa?”, mục tiêu của xác minh là phát hiện các lỗi lập trình Thẩm định là sự kiểm tra xem phần mềm có thỏa mãn được yêu cầu của người sử dụng không, nó chú trọng vào sản phẩm cuối cùng khi bàn giao cho khách hàng, mục tiêu là phát hiện các lỗi về thiết kế, về đặc tả Một hệ thống xây dựng đúng đặc tả, nhưng chưa chắc đã đáp ứng được yêu cầu của khách hàng, vì đặc tả có thể sai, thiết kế có thể thiếu chi tiết
2.1.3 Các mục tiêu của kiểm thử
Theo tài liệu [7], các bên liên quan trong quy trình kiểm thử phần mềm bao gồm các lập trình viên, kiểm thử viên, quản trị dự án và khách hàng Mỗi đối tượng này đều
có những cái nhìn khác nhau về mục tiêu của kiểm thử
Chương trình hoạt động được: Các lập trình viên thường chỉ quan tâm
đến khía cạnh là làm thế nào để chương trình hoạt động được trong các điều kiện thông thường
Chương trình không hoạt đông được: Lập trình viên ít khi quan tâm đến
một khía cạnh khác của chương trình là khi nào thì chương trình không hoạt động được, làm thế nào khi chương trình bị lỗi
Giảm rủi ro của lỗi: Nhà quản trị phần mềm thường quan tâm đến khía
cạnh là giảm rủi ro của lỗi gây ra Hầu hết các hệ thống phần mềm phức tạp đều chứa lỗi - là nguyên nhân hệ thống thất bại Bởi vậy nếu các lỗi được phát hiện và sửa trong khi thực hiện kiểm thử, tỷ lệ hệ thống gặp rủi
ro sẽ giảm
Giảm chi phí của việc kiểm thử: Chi phí cho việc kiểm thử bao gồm chi
phí thiết kế, bảo trì và thực thi các ca kiểm thử; chi phí phần tích kết quả thực hiện của mỗi ca kiểm thử; chi phí tài liệu hóa các ca kiểm thử và chi phí cho hệ thống hoạt động và tài liệu hóa các hoạt động đó Khách hàng
Trang 13thường mong muốn là giảm các chi phí của việc kiểm thử nhưng vẫn đảm
Trong các hệ thống không trạng thái (stateless systems), giá trị đầu ra chỉ phụ thuộc duy nhất vào giá trị đầu vào hiện tại, các ca kiểm thử thường rất đơn giản Ví dụ như là chương trình tính bình phương của một số như ở trên
Trong các hệ thống hướng trạng thái (state-oriented systems), giá trị đầu ra của chương trình phụ thuộc vào cả trạng thái hiện tại của hệ thống và giá trị đầu vào hiện tại, thì một ca kiểm thử có thể chứa một chuỗi các cặp <giá trị đầu vào, giá trị đầu ra mong muốn> Ví dụ như trong hệ thống ATM, hệ thống chuyển điện thoại, hệ thống đèn chiếu sáng và các hệ thống hướng trạng thái khác
Lựa chọn các giá trị đầu vào: Việc lựa chọn này dựa vào đặc tả yêu cầu, mã nguồn hoặc mong muốn của chúng ta
Tính toán giá trị đầu ra mong muốn: Hoạt động thứ ba là tính toán giá trị đầu ra mong muốn của chương trình tương ứng với giá trị đầu vào
Thiết lập môi trường kiểm thử của chương trình: Chuẩn bị môi trường kiểm thử của chương trình, ở bước này tất cẩ các giả định ngoài của chương trình phải được thỏa mãn Ví dụ: các hệ thống mạng, các cơ sở dữ liệu cần được thiết lập một cách đúng đắn
Tiến hành kiểm thử chương trình: Trong bước thứ năm, các kỹ sư kiểm thử thực hiện chương trình với các tập giá trị đầu vào và quan sát giá trị đầu ra thực tế của chương trình Để thực hiện một ca kiểm thử, các giá trị đầu vào phải được cung cấp cho chương trình ở các thời điểm khác nhau
Phân tích kết quả kiểm thử: Bước cuối cùng là phân tích các kết quả kiểm thử
để so sánh kết quả đầu ra thực tế với kết quả đầu ra mong muốn Độ phức tạp của phép so sánh này phụ thuộc vào độ phức tạp của dữ liệu quan sát Cuối
Trang 14cùng là đưa ra quyết định về kết quả hoạt động của chương trình là thỏa mãn
(pass), không thoải mãn (fail) yêu cầu của người dùng hay không đưa ra được
quyết định
2.1.6 Các mức độ kiểm thử
Kiểm thử phần mềm là một chuỗi các hoạt động tiến hình song song cùng hoạt động phát triển phần mềm, từ lập kế hoạch và kiểm soát quá trình kiểm thử, phân tích yêu cầu và thiết kế ca kiểm thử, viết ca kiểm thử, tiến hành kiểm thử phần mềm, đánh giá các kết quả kiểm thử, báo cáo và tổng hợp các hoạt động kết thúc quá trình kiểm thử Mô hình chữ V ở Hình 2.1 sẽ cho chúng ta thấy mối liên hệ giữa hoạt động phát triển và hoạt động kiểm thử
Hình 2.1 Mô hình chữ V trong phát triển phần mềm
Các hoạt động kiểm thử bao gồm: kiểm thử đơn vị, kiểm thử tích hợp, kiểm thử
hệ thống và kiểm thử chấp nhận Mỗi hoạt động này tương ứng với các pha trong phát triển phần mềm từ đặc tả yêu cầu của khách hàng đến hoạt động lập trình
Kiểm thử đơn vị được các lập trình viên thực hiện độc lập trên các đơn vị chương trình, như là các lớp và các hàm
Kiểm thử tích hợp được thực hiện bởi các kỹ sư lập trình và kỹ sư kiểm thử phần mềm nhằm đảm bảo rằng chương trình có thể hoạt động đúng khi tích hợp các đơn vị lại với nhau Kiểm thử tích hợp tương đương với việc kiểm tra thiết kế chi tiết, xem chương trình có thoải mãn thiết kế chi tiết hay không
Kiểm thử hệ thống được thực hiện bởi kỹ sư kiểm thử và sử dụng nhiều phương pháp, kỹ thuật khác nhau để tìm ra các lỗi, sửa lỗi và đảm bảo không phát sinh những lỗi mới Kiểm thử hệ thống là một pha rất quan trọng trong quy trình phát triển phần
Trang 15mềm nhằm đảm bảo chất lượng của phần mềm trước khi bàn giao sản phẩm cho khách hàng
Kiểm thử chấp nhận được thực hiện bởi khách hàng, những người sẽ kiểm tra xem phần mềm có đáp ứng được yêu cầu của người dùng hay không Quá trình kiểm thử này không nhằm mục đích tìm ra lỗi mà là đo xem sản phẩm có đáp ứng được nhu cầu của người dùng hay không
2.1.7 Các giới hạn của kiểm thử
Lý tưởng nhất là tất cả các chương trình đều phải hoạt động đúng, không có lỗi xảy ra trong chương trình Nhưng thực tế là để chứng minh được một chương trình là hoạt động đúng thì khách hàng và các nhà lập trình đều phải dựa vào việc kiểm thử phần mềm Theo [9], ta xem xét đến hai giới hạn lớn của kiểm thử:
Kiểm thử có nghĩa là thực thi một chương trình với một tập con đúng đắn của miền giá trị đầu vào của chương trình Một tập con đúng đắn của miền giá trị đầu vào được chọn bởi vì các chi phí phần mềm không cho phép một tập con lớn hơn được chọn, ví dụ như là tập các đầu vào đầy đủ Kiểm thử với tập các đầu vào đầy đủ được gọi là kiểm thử toàn diện (kiểm thử “vét cạn”) Vì vậy, cần kiểm thử một chương trình với một tập con nhỏ của miền giá trị đầu vào đặt ra một giới hạn cơ bản trên hiệu quả của việc kiểm thử Mặt khác, cho dù một chương trình thỏa mãn một tập kiểm thử thì chúng ta cũng không thể kết luận rằng chương trình là hoàn toàn đúng đắn
Khi chúng ta chọn một tập con của miền giá trị đầu vào, chúng ta sẽ phải đối phó với vấn đề kiểm chứng tính đúng đắn của các giá trị đầu ra chương trình với các giá trị đầu vào riêng biệt Cơ chế đánh giá tính đúng đắn của giá trị
đầu ra chương trình được gọi là oracle (phán xét kiểm thử) Quyết định tính
đúng đắn của một giá trị đầu ra của chương trình là một công việc không tầm thường Một chương trình được xem xét là không thể kiểm thử được
(nontestable) khi nó gặp phải hai vấn đề sau:
o Không tồn tại một phán xét kiểm thử
o Quá khó để đưa ra quyết định đây có phải đầu ra đúng đắn
Nếu không có cơ chế để đánh giá tính đúng đắn của một đầu ra chương trình hoặc nó tốn quá nhiều thời gian để đánh giá đầu ra, thì sẽ không đạt được kết quả mong muốn của việc thực hiện kiểm thử
2.2 Các kỹ thuật kiểm thử phần mềm
Trong kiểm thử phần mềm, chúng ta thường dùng hai kỹ thuật chính là kiểm thử tĩnh (static testing) và kiểm thử động (dynamic testing) Kiểm thử động bao gồm các kỹ thuật: kiểm thử hộp đen (black box testing) và kiểm thử hộp trắng (white box testing)
Kỹ thuật kiểm thử hộp đen là một kỹ thuật quan trọng trong hoạt động kiểm thử phần mềm, khái niệm “hộp đen” ở đây là chỉ việc kiểm thử viên không biết chương
Trang 16trình bên trong được cài đặt như thế nào, họ chỉ biết rằng nó phải làm gì, và làm như thế nào để thỏa mãn các yêu cầu đặc tả - đã được cụ thể hóa thành các ca kiểm thử [9] Một số phương pháp được áp dụng trong kỹ thuật kiểm thử hộp đen: kỹ thuật phân lớp tương đương (Equivalence partitioning), kỹ thuật phân tích giá trị biên (Boundary value analysis), kỹ thuật dùng bảng quyết định (Decision table), kỹ thuật dùng bảng chuyển trạng thái (State transition) và kỹ thuật kiểm thử ca sử dụng (Use case testing)
Kỹ thuật kiểm thử hộp trắng là một kỹ thuật được áp dụng khi ta đã biết chương trình bên trong được lập trình như thế nào, cấu trúc chương trình, các dòng điều khiển,
và dòng dữ liệu chạy ra sao Kỹ thuật này thường tốn thời gian, công sức để thực hiện, nên thường chỉ áp dụng ở mức độ kiểm thử đơn vị - kiểm tra từng lớp, từng bộ phận
mà không thực hiện ở các mức độ cao hơn Các kỹ thuật kiểm thử hộp trắng là: kiểm thử luồng điều khiển, kiểm thử dòng dữ liệu và kiểm thử miền
Tuy có rất nhiều phương pháp kiểm thử phần mềm, nhưng trong nội dung của luận văn này, chúng ta đi sâu vào việc kết hợp kiểm chứng mô hình, kỹ thuật phân lớp tương đương và kỹ thuật kiểm thử đột biến Vì vậy, luận văn sẽ trình bày rõ hơn về hai
kỹ thuật phân lớp tương đương và kỹ thuật kiểm thử đột biến
2.2.1 Kỹ thuật phân lớp tương đương
Kỹ thuật phân lớp tương đương được áp dụng khi miền dữ liệu đầu vào quá lớn
để có thể kiểm tra từng giá trị đầu vào Miền giá trị đầu vào sẽ được chia thành một số hữu hạn các miền nhỏ hơn có tính chất giống nhau Mỗi miền nhỏ hơn này sẽ được gọi
là một phân lớp tương đương, các giá trị đầu vào trong một lớp tương đương sẽ cho cùng một kết quả đầu ra
Việc phân lớp tương đương sẽ làm giảm số lượng các ca kiểm thử, các bộ giá trị đầu vào Số lượng bộ giá trị đầu vào giảm xuống còn bằng số lượng các miền nhỏ Theo [7], ưu điểm của phương pháp phân hoạch tương đương là:
Chỉ cần một số lượng nhỏ ca kiểm thử để có thể bao phủ cả một miền giá trị đầu vào lớn
Khả năng tìm ra lỗi trên cả miền bao phủ là cao hơn so với phương pháp lựa chọn miền giá trị đầu vào, và ca kiểm thử ngẫu nhiên
Phương pháp này áp dụng được cho cả miền giá trị đầu vào và miền giá trị đầu ra
2.2.2 Phương pháp kiểm thử đột biến (mutation testing)
Kiểm thử đột biến là một cách để đánh giá và cải tiến chất lượng của một bộ ca kiểm thử bằng việc kiểm tra nếu các ca kiểm thử của nó có thể phát hiện ra một số lỗi
đã được chèn vào trong chương trình Các lỗi thường được đưa vào chương trình bằng việc thay đổi cú pháp của mã nguồn theo các mẫu của lỗi lập trình thông thường
Những độ lệch (deviation) trong mã lệnh được gọi là các đột biến (mutants) Các phiên
bản khác nhau của chương trình từ các lỗi này được gọi là các đột biến Thường thì mỗi đột biến chỉ bao gồm một sự biến đổi Ví dụ về các phép biến đổi thông thường
Trang 17bao gồm việc đổi tên biến, thay thế các toán tử bằng các toán tử tương đương, thay đổi trong toán tử Boolean và biểu thức đại số Ở đây, ta chỉ xem xét các phép biến đổi về
cú pháp Theo [1], số lượng và loại phép đột biến phụ thuộc vào ngôn ngữ lập trình và
đã được xác định gọi là toán tử đột biến (mutation operators)
Một toán tử đột biến là một luật được viết lại để định nghĩa cách các thuật ngữ
cụ thể trong ngôn ngữ lập trình được thay thế bằng các đột biến Với việc thay thế một toán tử đột biến vào trong chương trình gốc thì sẽ tạo ra một đột biến mới Sau khi, tập các đột biến được sinh ra, các ca kiểm thử được chạy trên chương trình gốc và trên mỗi biến thể Nếu ca kiểm thử có thể phát hiện được một đột biến trong chương trinh gốc, ví dụ như là ca kiểm thử vượt qua được trong chương trình gốc nhưng trượt trong
một đột biến, thì chúng ta nói rằng ca kiểm thử này đã “loại bỏ” (kill) được một đột
biến Mục tiêu là phát triển một bộ các ca kiểm thử có thể loại bỏ được tất cả các đột
biến Theo [9], tỷ lệ đột biến (Mutation score) của một tập kiểm thử là tỷ lệ phần trăm
số các đột biến bị loại bỏ bởi tập các ca kiểm thử
1 proctype tritype (int a; int b; int c) {
2 do
3 :: (a <= c-b) -> printf (" This is not a triangle\n");
4 :: (a <= b-c) -> printf (" This is not a triangle\n");
5 :: (b <= a-c) -> printf (" This is not a triangle\n");
6 :: (a == b && b == c) -> printf (" This is a equilateral\n");
7 :: (a == b) -> printf (" This is a isosceles\n");
8 :: (b == c) -> printf (" This is a isosceles\n");
9 :: (c == a) -> printf (" This is a isosceles\n");
10 ::else -> printf (" This is a scalene\n");
Hình 2.2 Chương trình kiểm tra ba cạnh của tam giác
Hình 2.2 là đoạn mã bằng ngôn ngữ PROMELA (ngôn ngữ của công cụ SPIN) kiểm tra ba cạnh của tam giác và trả về kết quả là loại tam giác Ví dụ về toán tử đột biến có thể viết lại là mỗi dấu “==” sẽ được thay thế bằng dấu “>=” Chúng ta có năm biến thể, tương đương với năm phép biến đổi trong chương trình
Ta có một tập các ca kiểm thử của chương trình là:
Trang 18TC6: <(1, 5, 3), not a triangle>
TC7: <(5, 3, 1), not a triangle>
TC8: <(3, 4, 5), scalene>
Ta có các phép biến đổi của chương trình như sau:
Mutant 1: biến đổi dòng 6 thành
:: (a >= b && b == c) -> printf (" This is a
equilateral\n");
Mutant 2: biến đổi dòng 6 thành
:: (a == b && b >= c) -> printf (" This is a
equilateral\n");
Mutant 3: biến đổi dòng 7 thành
:: (a >= b) -> printf (" This is a isosceles\n");
Mutant 4: biến đổi dòng 8 thành
:: (b >= c) -> printf (" This is a isosceles\n");
Mutant 5: biến đổi dòng 9 thành
:: (a >= c) -> printf (" This is a isosceles\n");
Nếu ta chạy lại chương trình sau khi đã biến đổi cùng với bộ ca kiểm thử, chúng
ta sẽ thu được kết quả sau:
Mutant 1 và Mutant 2: tất cả các ca kiểm thử đều thỏa mãn Nói cách khác
là Mutant 1 và Mutant 2 không bị “kill”
Mutant 3: chương trình bị lỗi ở TC4 và TC7
Mutant 4: chương trình bị lỗi ở TC4, TC6 và TC7
Mutant 5: chương trình bị lỗi ở TC4 và TC7
Nếu tính toán tỷ lệ đột biến, chúng ta sẽ thấy rằng với năm đột biến thì chỉ ba trong năm đột biến được phát hiện ra, và tỷ lệ là 60% Vì thế ta cần thêm các ca kiểm thử để phát hiện ra đột biến Mutant 1 và Mutant 2
TC9: (<3, 2, 2>, isosceles)
TC10: (<3, 3, 2>, isosceles)
Lúc này thì bộ ca kiểm thử mới phát hiện được hết các đột biến, và tỷ lệ đột biến bây giờ là 100%
Theo [9], kỹ thuật kiểm thử đột biến được thực hiện qua các bước sau:
Bước 1: Bắt đầu với một chương trình P, và một tập các ca kiểm thử T cho trước được cho là chính xác
Bước 2: Thực hiện các ca kiểm thử trong tập T trên chương trình P Nếu một ca kiểm thử bị lỗi, có nghĩa là đầu ra của chương trình không đúng,
Trang 19chương trình P cần phải thay đổi và kiểm thử lại Nếu không có lỗi xảy ra, ta tiếp tục thực hiện bước 3
Bước 3: Tạo một bộ các đột biến {Pi}, mỗi đột biến là một thay đổi nhỏ trong cú pháp của chương trình P
Bước 4: Thực hiện các ca kiểm thử trong T trên mỗi đột biến Pi Nếu đầu ra của đột biến Pi khác với đầu ra của chương trình gốc P, thì đột biến Pi được xem là không chính xác và bị loại bỏ bởi ca kiểm thử Nếu Pi có kết quả đầu
ra chính xác như kết quả của chương trình gốc P khi kiểm thử trong T thì một trong các trường hợp sau là đúng:
o P và Pi là tương đương Có nghĩa là hành vi của chúng không khác nhau bởi bất kỳ tập các ca kiểm thử nào Lưu ý là rất khó để đánh giá được là
P và Pi tương đương trong thực tế
o Pi có thể bị loại bỏ Có nghĩa là, các ca kiểm thử đã không loại bỏ được đột biến Pi Trong trường hợp này, các ca kiểm thử mới sẽ được tạo ra Bước 5: Tính toán tỷ lệ đột biến của tập các ca kiểm thử T Tỷ lệ đột biến =
, trong đó D là các đột biến đã bị loại bỏ, N là tổng số đột biến, E là số đột biến tương đương
Bước 6: Nếu tỷ lệ đột biến ở bước 5 là không cao, thì cần phải thiết kế các
ca kiểm thử mới phân biệt Pi với P, thêm các ca kiểm thử mới vào tập T, vào quay lại bước 2 Nếu tỷ lệ đột biến ở mức độ tương đương với kỳ vọng, thì chấp nhận tập T như là một độ đo tốt cho tính đúng đắn của chương trình P với tập các đột biến Pi,và ngừng thiết kế các ca kiểm thử mới
Theo [9], kiểm thử đột biến đưa ra hai giả định quan trọng:
Giả thuyết các lập trình viên có trình độ (Competent Programmer
Hypothesis): giả sử rằng các lập trình viên đều có trình độ, họ không tạo ra
các chương trình một cách ngẫu nhiên Chúng ta có thể giả sử rằng một lập trình viên sẽ viết ra các chương trình đúng đắn với một vài lỗi nhỏ Các lỗi nhỏ này được xem như là một sự sai lệch nhỏ so với chương trình gốc Các lỗi này thường được gọi là các toán tử đột biến, gây ra những sai lệch nhỏ một cách có hệ thống trong chương trình
Hiệu ứng cặp đôi (Coupling Effect): Giả định này được đưa ra vào năm
1978 bởi nhà khoa học deMillo và đồng sự Giả định này nói rằng các lỗi phức tạp là những cặp lỗi đơn giản và nếu mà một bộ kiểm thử phát hiện
ra tất cả các lỗi đơn giản trong chương trình thì sẽ phát hiện ra các lỗi phức tạp
Kiểm thử đột biến giúp cho các kiểm thử viên có thể tự tin về chương trình của mình Nhưng số lượng các đột biến được sinh ra, và các ca kiểm thử để loại bỏ được
nó là rất lớn Vì vậy, chúng ta cần có chiến lược để có thể áp dụng kỹ thuật kiểm thử đột biến một cách hiệu quả
Trang 20Chương 3 Kiểm chứng mô hình
Chương 3 trình bày các khái niệm về kiểm chứng mô hình, quy trình thực hiện việc kiểm chứng mô hình, các ưu nhược điểm, thuộc tính của mô hình và các công cụ
để kiểm chứng
3.1 Khái niệm kiểm chứng mô hình
Trước khi nói về kiểm chứng mô hình, thì chúng ta cần nhắc đến khái niệm về
các phương pháp hình thức (formal methods) Theo [3], các phương pháp hình thức
được coi như là việc áp dụng các kiến thức toán học ứng dụng vào việc mô hình hoá
và phân tích các hệ thống thông tin Các phương pháp hình thức là một trong những kỹ thuật thẩm định các hệ thống thông tin được đánh giá cao Ngày nay, các phương pháp hình thức, và kiểm chứng hình thức đã được áp dụng trong các viện nghiên cứu và giảng dạy trong các trường đại học
Kỹ thuật kiểm chứng dựa vào mô hình là căn cứ vào mô hình mô tả các hành vi
có thể của hệ thống bằng các công thức toán học chính xác và không nhập nhằng Các
mô hình hệ thống được đi kèm theo bởi các thuật toán dò tìm tất cả các trạng thái của
mô hình hệ thống một cách tự động Điều này cung cấp các nền tảng cho một loạt các
kỹ thuật thẩm định từ thăm dò vét cạn (kiểm chứng mô hình) tới kiểm tra bằng thực nghiệm trên mô hình (mô phỏng) hoặc trên thực tế (kiểm thử)
Kiểm chứng mô hình là một kỹ thuật trong kiểm chứng hình thức (Formal
Verification) Nó nằm trong mối tương quan giữa đặc tả hình thức (Formal Specification) và sự tổng hợp hình thức (Formal Synthesis)
Hình 3.1 Mối liên hệ giữa kiểm chứng hình thức, kiểm chứng mô hình
và khái niệm hình thức
Kiểm chứng mô hình (Model checking) là một kỹ thuật automat dùng để kiểm chứng các hệ phản vệ (re-active systems) có hữu hạn trạng thái, ví dụ như là các thiết
Trang 21kế chuỗi mạch và các giao thức truyền thông (protocols) Các đặc tả được thể hiện trong logic mệnh đề thời gian (propositional temporal logic) và hệ phản vệ được mô hình hoá thành một đồ thị chuyển trạng thái (state – transition graph) Một cách tìm kiếm hiệu quả đã được sử dụng để quyết định một cách tự động xem đặt tả có được thoả mãn bởi đồ thị chuyển trạng thái hay không Kỹ thuật này đã được phát triển từ năm 1981 bởi Clarke và Allen Emerson Trong khi đó, Quielle và Sifakis cũng độc lập phát triển một kỹ thuật kiểm chứng tương tự ngay sau đó
Kỹ thuật kiểm chứng mô hình có một số ưu điểm quan trọng trong việc chứng minh các lý thuyết về cơ khí học hoặc kiểm tra việc kiểm chứng trong các mạch và phương thức giao tiếp Quan trọng nhất là nó hoạt động tự động ở mức cao Thông thường, người dùng cung cấp một thể hiện ở mức độ cao của mô hình và đặc tả cần kiểm tra Bộ kiểm chứng mô hình sẽ chạy đến khi nó trả về kết quả là đúng (true), tức
là mô hình thoả mãn được các đặc tả, hoặc nó sẽ đưa ra các phản ví dụ (counterexample) để chỉ ra rằng mô hình không được thoả mãn Các phản ví dụ này rất quan trọng trong việc tìm kiếm các điểm có thể gây lỗi trong các hệ phản vệ phức tạp
Kiểm chứng mô hình thực ra chính là quá trình khám phá tất cả các trạng thái
có thể của hệ thống bằng phương pháp vét cạn Nó tương tự như việc vét cạn tất cả các khả năng đặt quân hậu trong bài toán 8 – hậu, hay là tìm kiếm tất cả các nước có thể thắng trong cờ vua Kiểm chứng mô hình sẽ là một thách thức lớn khi mà không gian trạng thái tìm kiếm trở lên lớn hơn Kiểm chứng mô hình có thể tìm ra nhiều lỗi tiềm
ẩn mà chúng ta không tìm được bằng phương pháp kiểm thử hay mô phỏng thông thường
Các thuộc tính thông thường có thể được kiểm tra bằng kiểm chứng mô hình là các đặc điểm định tính tự nhiên: Kết quả sinh ra có đúng không? Hệ thống có thể trải qua một tình huống khoá chết không? Khi hai tiến trình tương tranh đều chờ nhau thì
có gây ra hiện tượng treo ở các phần còn lại của hệ thống không? Các thuộc tính thời gian cũng có thể được kiểm chứng: Một khoá chết có thể xảy ra trong 1 giờ sau khi hệ thống phục hồi không? Hay, một phản hồi có luôn được nhận sau mỗi 8 phút không? Kiểm chứng mô hình yêu cầu một phát biểu chính xác và không nhập nhằng của các thuộc tính được kiểm chứng
Mô hình hệ thống thường được sinh ra một cách tự động từ một mô tả mô hình được đặc tả trong vài ngôn ngữ lập trình thích hợp như C, Java hoặc các ngôn ngữ đặc
tả phần cứng như là Verilog hay VHDL Lưu ý rằng: các đặc tả thuộc tính quy định hệ thống nên làm gì và không được làm gì, trong khi đó mô hình định vị cách hệ thống hoạt động Bộ kiểm chứng mô hình thực hiện chính xác tất cả các trạng thái hệ thống
để kiểm chứng xem chúng có thoả mãn thuộc tính mong đợi Nếu một trạng thái không thoả mãn thuộc tính đang đánh giá, Bộ kiểm chứng mô hình sẽ cung cấp một phản ví
dụ Phản ví dụ mô tả cách để đi từ trạng thái ban đầu của hệ thống đều trạng thái vi phạm của thuộc tính đang được kiểm chứng Với sự trợ giúp của một máy mô phỏng,
Trang 22người dùng có thể chạy lại tình huống vi phạm, nó chứa các thông tin hữu ích cho việc
gỡ lỗi, và đáp ứng của hệ thống
3.2 Quy trình kiểm chứng mô hình
Các giai đoạn trong quy trình kiểm chứng mô hình (cách giai đoạn này được mô
tả trong hình vẽ 2.3 ở dưới):
Hình 3.2 Cách tiếp cận kiểm chứng mô hình
Giai đoạn mô hình hoá (Modeling phase):
o Mô hình hệ thống đang xem xét sử dụng ngôn ngữ mô tả mô hình của bộ kiểm chứng
o Ở lần kiểm thử tính đúng đắn (sanity check) đầu tiên và đánh giá nhanh
mô hình sẽ thực hiện vài mô phỏng;
o Hình thức hoá thuộc tính cần kiểm chứng dùng ngôn ngữ đặc tả thuộc tính
Giai đoạn thực thi (Running phase): chạy bộ kiểm chứng mô hình để kiểm tra
tính hợp lệ của thuộc tính trong mô hình hệ thống
Giai đoạn phân tích (Analysis phase):
o Nếu thuộc tính được thoả mãn? → Tiến hành kiểm tra thuộc tính tiếp theo (nếu có);
o Nếu thuộc tính bị vị phạm? →
1 Phân tích phản ví dụ được sinh ra bởi bộ mô phỏng;
2 Làm mịn mô hình, thiết kế, hoặc thuộc tính;
3 Lặp lại toàn bộ thủ tục trên
Trang 23o Nếu bị tràn bộ nhớ? → Cố gắng thu gọn mô hình và thử lại
Thêm nữa là toàn bộ quá trình kiểm chứng nên được lập kế hoạch, quản lý và tổ
chức Quá trình này được gọi là tổ chức kiểm chứng
Mô hình hoá (Modeling) Điều kiện đầu vào cần thiết cho việc kiểm thử mô
hình là một mô hình của hệ thống đang được đánh giá và một đặc điểm hình thức của của thuộc tính cần kiểm chứng
Mô hình của các hệ thống mô tả hành vi của hệ thống theo một cách chính xác
và không nhập nhằng Chúng thường được biểu diễn bởi một otomat hữu hạn trạng thái (finite-state automata), là một tập hữu hạn các trạng thái và tập các phép chuyển Các trạng thái bao gồm thông tin về các giá trị hiện tại của biến, biểu thức đã được thực thi trước đó Các phép chuyển mô tả cách hệ thống chuyển từ một trạng thái này sang một trạng thái khác Trong các hệ thống thực tế, otomat hữu hạn trạng thái được
mô tả bằng một ngôn ngữ mô tả mô hình (model description language) như là các mở rộng tương ứng của ngôn ngữ C, Java
Để việc kiểm chứng được chính xác, các thuộc tính cần được mô tả một cách chính xác và không nhập nhằng Nó thường được mô tả bởi một ngôn ngữ đặc tả thuộc tính (property specification language) Ở đây chúng ta tập trung vào sử dụng logic thời
gian (temporal logic) như là một ngôn ngữ đặc tả thuộc tính, là một kiểu logic thích
hợp cho việc đặc tả các thuộc tính của các hệ thống thông tin Trong logic toán học, nó kiểm tra rằng đặc tả hệ thống là một mô hình của công thức logic thời gian Nó giúp giải thích ý nghĩa của cụm từ “Kiểm chứng mô hình” Logic thời gian là một mở rộng của logic mệnh đề truyền thống với các toán tử liên hệ tới hành vi của các hệ thống
Nó cho phép đặc tả cho một loạt các thuộc tính của hệ thống như là tính đúng đắn của chức năng (functional correctness - hệ thống làm những gì mà nó được mong muốn là
sẽ thực hiện), khả năng có thể đạt tới được (reachability - nó có thể kết thúc trạng thái khoá chết?), tính an toàn (safety - điều tồi tệ sẽ không bao giờ xảy ra?), tính hoạt động được (liveness – những điều tốt đẹp sẽ xảy ra?), tính ổn định (fairness – dưới các điều kiện giống nhau, một sự kiện diễn ra lặp lại?), và các thuộc tính thời gian thực (hệ thống sẽ thực hiện đúng giờ?)
Chạy Bộ kiểm chứng (Running the Model Checker) Đầu tiên, Bộ kiểm
chứng khởi tạo việc thiết lập các lựa chọn và các chỉ dẫn khác nhau thích hợp để thực hiện việc kiểm chứng vét cạn Sau đó, quá trình kiểm chứng mô hình thật sự sẽ diễn ra Việc kiểm chứng này cơ bản là việc dùng một cách tiếp cận thuật toán duy nhất để xem xét tính hợp lệ của thuộc tính đang đánh giá xem nó có được kiểm tra trong tất cả các trạng thái của mô hình hệ thống
Phân tích các kết quả (Analyzing the Results) Có ba trường hợp có thể xảy
ra: thuộc tính được đặc tả thoả mãn mô hình đã cho hoặc không thoả mãn, hoặc mô hình trở nên quá to đối với các giới hạn vật lý của bộ nhớ máy vi tính
Trang 24Trong trường hợp thuộc tính thoả mãn, các thuộc tính tiếp theo sẽ có thể được kiểm tra, hoặc trường hợp tất cả các thuộc tính đã được kiểm tra, thì mô hình sẽ được kết luận là thoả mãn tất cả các thuộc tính mà nó đòi hỏi
Khi một thuộc tính không thoả mãn, kết quả tiêu cực có thể xảy ra do các nguyên nhân khác nhau Có thể là do quá trình mô hình hoá bị lỗi mô hình không phản ánh đúng thiết kế của hệ thống Chúng ta có thể sửa lại mô hình và việc kiểm chứng bắt đầu lại với mô hình đã được cải tiến.Việc kiểm chứng lại này bao gồm cả kiểm chứng những thuộc tính khác đã được kiểm chứng trước đó trong mô hình lỗi vì những phép kiểm chứng này không có giá trị với mô hình mới Nếu lỗi phân tích chỉ ra rằng không có sự sai khác một cách bất thường giữa thiết kế và mô hình của nó, sau đó có thể là một lỗi thiết kế hoặc một thuộc tính lỗi đã xảy ra Trường hợp có một lỗi thiết
kế, việc kiểm chứng sẽ bao gồm cả kết quả sai, và thiết kế (cùng với mô hình của nó) phải được cải tiến Nếu là do lỗi của thuộc tính đã không phải ánh đúng yêu cầu phi hình thức để kiểm chứng thì thuộc tính này cần được sửa lại, và một quá trình kiểm chứng mới của mô hình sẽ được thực hiện Bởi vì mô hình không thay đổi nên ta không cần kiểm chứng lại các thuộc tính đã kiểm chứng trước đó Một thiết kế được gọi là kiểm chứng khi và chỉ khi tất cả các thuộc tính được kiểm tra cẩn thận với một
mô hình đúng
Khi mô hình quá lớn để có thể điều khiển – không gian trạng thái của các hệ thống thật có thể lớn hơn rất nhiều so với khả năng lưu trữ của các bộ nhớ hiện tại – có nhiều cách khác nhau để tiếp tục Một khả năng là ứng dụng các kỹ thuật để cố gắng khai thác các quy tắc ẩn trong cấu trúc của mô hình Ví dụ của những kỹ thuật này là thể hiện các không gian trạng thái bằng các kỹ thuật ký hiệu như là các lược đồ quyết định nhị phân (binary decision diagrams) hay làm giảm thứ tự riêng phần (partial order reduction) Một cách khác để giải quyết các không gian trạng thái quá lớn là từ bỏ tính chính xác của kết quả kiểm chứng Các cách tiếp cận kiểm chứng xác suất khám phá chỉ một phần của không gian trạng thái trong khi đưa ra một sự hy sinh (một cách không đáng kể) trong độ phủ của kiểm chứng
Tổ chức kiểm chứng (Verification Organization).Toàn bộ quá trình kiểm
chứng mô hình nên được tổ chức tốt, cấu trúc tốt và lên kế hoạch cẩn thận Chúng ta nên quản lý phiên bản và cấu hình của các lần kiểm chứng Các thông tin này cần được văn bản hoá và bảo trì cần thận để quản lý quá trình kiểm chứng mô hình thực tế và cho phép thực hiện lại các quá trình đó
3.3 Ưu và nhược điểm của kiểm chứng mô hình
3.3.1 Ưu điểm của kiểm chứng mô hình
Đây là một cách tiếp cận kiểm chứng phổ biến mà có thể áp dụng trong các ứng dụng khác nhau như các hệ thống nhúng, kỹ nghệ phần mềm và thiết kế phần cứng
Trang 25Hỗ trợ kiểm chứng cục bộ (partial verification), ví dụ như các thuộc tính có thể được kiểm chứng độc lập, và cho phép tập trung vào các thuộc tính quan trọng trước Nó không đòi hỏi đặc tả các yêu cầu một cách hoàn chỉnh
Không ảnh hưởng tới khả năng xảy ra của một lỗi được phát hiện; điều này trái ngược với việc kiểm thử và mô phỏng – vốn có mục đích là tìm vết những lỗi
Phương pháp này được yêu thích trong quy trình phát triển phần mềm nhanh – rất được ưa thích trong công nghiệp
Có thể dễ dàng tích hợp với vòng đời phát triển sẵn có;
Có nền tảng đúng đắn và chính xác; nó dựa vào lý thuyết về các thuật toán đồ thị, các cấu trúc dữ liệu và logic
3.3.2 Nhược điểm của kiểm chứng mô hình
Phương pháp này chủ yếu thích hợp với các ứng dụng hướng điều khiển hơn là các ứng dụng hướng dữ liệu bởi vì dữ liệu thường vượt quá các miền vô hạn Khả năng áp dụng của nó trong lĩnh vực liên quan đến các vấn đề mang tính quyết định; trong các hệ thống trạng thái vô hạn, hoặc hệ lập luận với các kiểu
dữ liệu trừu tượng (yêu cầu logic không tất định hoặc bán tất định), kiểm chứng mô hình không mang lại nhiều hiệu quả tính toán
Nó kiểm chứng một mô hình hệ thống, và không phải là một hệ thống thật sự (một sản phẩm hay bản mẫu) của nó; bất kỳ kết quả nào cũng chỉ tốt tương ứng với mô hình hệ thống Các kỹ thuật bổ sung như là kiểm thử là cần thiết để tìm
ra lỗi sản xuất (đồi với phần cứng) và lỗi lập trình (đối với phần mềm)
Nó chỉ kiểm tra các yêu cầu đã được trạng thái, nó không bảo đảm tính toàn vẹn Tính hợp lý của các thuộc tính không được kiểm chứng có thể không được đảm bảo
Nó phải đối mặt với vấn đề bùng nổ không gian trạng thái, số các trạng thái cần cho mô hình hệ thống chính xác có thể dễ dàng vượt quá bộ nhớ của máy vi tính
Việc dùng nó yêu cầu một vài kinh nghiệm trong việc tìm ra các trừu tượng hoá phù hợp để làm cho các mô hình hệ thống nhỏ hơn và trạng thái của các thuộc tính trong logic hình thức dùng được
Nó không đảm bảo cho ra các kết quả chính xác hoàn toàn: vì cũng như các công cụ khác thì Bộ kiểm chứng cũng là một phần mềm có thể có lỗi
Trang 26Nó không cho phép kiểm chứng tính tổng quát: thông thường, các hệ thống kiểm chứng với một số tuỳ ý các thành phần, hoặc các hệ thống đã được tham
số hoá là không thể bị lừa dối Các hệ thống này có thể được kiểm chứng bằng cách dùng các chứng minh
3.4 Logic thời gian tuyến tính (Linear Temporal Logic - LTL)
3.4.1 Trạng thái thời gian tuyến tính (Linear-Time Behavior)
Theo [3], để phân tích một hệ thống máy tính được thể hiện bằng một hệ thống chuyển (transition system), cả hai cách tiếp cận dựa vào hành động (action-based) và dựa vào trạng thái (state-based) đều có thể sử dụng được Cách tiếp cận hướng trạng thái trừu tượng hóa từ các hành động thay vì chỉ trừu tượng hóa các nhãn chuỗi trạng thái được lấy ra để xem xét Ngược lại thì cách tiếp cận hướng hành động trừu tượng hóa từ các trạng trái và liên hệ tới các nhãn hành động của các phép chuyển
a Các hệ thống chuyển (transition systems)
Theo [3], các hệ thống chuyển thường được dùng trong khoa học máy tính như
là các mô hình để mô tả hành vi của các hệ thống Thông thường, chúng là những đồ thị có hướng với các đỉnh thể hiện cho các trạng thái, và các cạnh mô phỏng cho việc chuyển trạng thái Các phép chuyển đặc tả cách hệ thống có thể chuyển từ một trạng thái này sang một trạng thái khác
Ở đây chúng ta dùng các hệ thống chuyển với định danh hành động (action names) cho các phép chuyển và các mệnh đề nguyên tử cho các trạng thái Định danh hành động sẽ được dùng để mô tả cơ chế giao tiếp giữa các tiến trình Mệnh đề nguyên
tử được dùng để mô hình hóa các thuộc tính thời gian, chúng thường biểu biễn các sự thật một cách đơn giản về các trạng thái của hệ thống đang xem xét
Định nghĩa 3.1 Hệ thống chuyển (Transition System – TS)
Một hệ thống chuyển TS là một bộ (S, Act, →, I, AP, L), trong đó:
TS được gọi là hữu hạn nếu S, Act và AP là hữu hạn
Định nghĩa 3.2 Các tiền tố và hậu tố trực tiếp (Direct Predecessors and Successors)
Trang 27Với TS = (S, Act, →, I, AP, L) là một hệ thống chuyển Với mỗi trạng thái
và mỗi hành động , tập các hậu tố trực tiếp của s được định nghĩa như sau:
(3.1)
Công thức (3.1) chỉ ra rằng tập các hậu tố của trạng thái s với hành động là tập các trạng thái thuộc S, sao cho là kết quả của phép chuyển từ trạng
s sau khi thực hiện hành động ; tập các hậu tố của trạng thái s là tập hợp tất
cả các trạng thái tiếp theo của s với tất cả các hành động của Act
Tập các tiền tố trực tiếp của s được định nghĩa như sau:
(3.2)
Công thức (3.1) chỉ ra rằng tập các tiền tố của trạng thái s với hành động là tập các trạng thái thuộc S, sao cho là trạng thái xuất phát của phép
chuyển để đạt được trạng thái s sau khi thực hiện hành động ; tập các tiền tố
của trạng thái s là tập hợp tất cả các trạng thái xuất phát của s với tất cả các hành
động của Act
Định nghĩa 3.3 Trạng thái kết thúc (Terminal States)
Trạng thái s trong hệ thống chuyển TS được gọi là kết thúc khi và chỉ khi tập các hậu tố của s rỗng: Post(s) = ɵ
Định nghĩa 3.4 Thực thi (Execution)
Một thực thi của hệ thống chuyển TS là một đường thực thi từ ban đầu và dài nhất
Định nghĩa 3.5 Các trạng thái có thể đạt được (Reachable States)
Với TS = (S, Act, →, I, AP, L) là một hệ thống chuyển Một trạng thái
được gọi là đạt được trong hệ chuyển TS nếu có tồn tại một đường thực thi từ ban đầu
và hữu hạn
Reach (TS) là ký hiệu của tập tất cả các trạng thái đạt được trong hệ thống chuyển TS
Cỡ của hệ thống chuyển thể hiện sự phát triển theo hàm mũ trong các thành phần,
ví dụ như là số biến trong một đồ thị chương trình hay số thành phần trong một hệ thống tương tranh Nó được gọi là vấn đề bùng nổ không gian trạng thái
Trang 28b Các đường và đồ thị trạng thái (Path and State graph)
Định nghĩa 3.6 Đồ thị trạng thái (state graph)
Đồ thị trạng thái của TS ký hiệu là G(TS) là một bộ (V, E) với các đỉnh V = S và
S và thuộc tập trạng thái hậu tố của trạng thái s
Định nghĩa 3.7 Đường dẫn (Path)
Một đường dẫn của hệ chuyển TS là một đường dẫn phân mảnh từ điểm bắt đầu
và dài nhất Tức là đường dẫn sẽ đi từ trạng thái bắt đầu đến trạng thái kết thúc của đồ thị
Paths(TS) là ký hiệu cho tập tất cả các đường dẫn trong TS Và Pathsfin (TS) là tập tất cả các đường dẫn khởi đầu, hữu hạn của TS (fin là từ viết tắt của finite – hữu hạn)
c Vết (Trace)
Định nghĩa 3.8 Vết và lần vết (Trace)
Với TS = (S, Act, →, I, AP, L) là một hệ thống chuyển không có trạng thái kết thúc Một vết của đường dẫn vô hạn π = s0 s1 … được định nghĩa là Trace (π) = L(s0) L(s1) … Vết của đường dẫn hữu hạn được định nghĩa là Trace ( ) = L(s0) L(s1) … L(sn)
Vết của một đường dẫn có thể là hữu hạn hoặc vô hạn
3.4.2 Thuộc tính thời gian tuyến tính
Các thuộc tính thời gian tuyến tính (Linear- Time properties) đặc tả các vết mà một hệ chuyển nên thể hiện Nói một cách khác là thuộc tính thời gian đặc tả hành vi
có thể chấp nhận được (được hy vọng) của hệ thống đang xem xét
Định nghĩa 3.9 Thuộc tính thời gian tuyến tính (LT Property)
Một thuộc tính thời gian tuyến tính trên tập các mệnh đề nguyên tử AP là một tập con của (2AP)ω
Trong đó (2AP)ω làký hiệu của tập từ được tạo ra từ các kết hợp vô hạn của các
từ trong 2AP Một thuộc tính thời gian tuyến tính là một ngôn ngữ (tập hợp) vô hạn các
Trạng thái thỏa mãn P, ký hiệu là khi
Trang 29Vì vậy, một hệ chuyển thỏa mãn thuộc tính thời gian tuyến tính P nếu tất cả các vết của nó đều thỏa mãn P, nếu tất cả các hành vi của nó là chấp nhận được Một trạng thái thỏa mãn P khi tất cả các vết bắt đầu từ trạng thái này đều thoả mãn P
3.4.3 Các thuộc tính an toàn (safety properties)
Các thuộc tính an toàn thường mô tả là “không có gì tồi tệ có thể xảy ra’ (nothing bad should happen) Ví dụ trong bài toán mutual – thuộc tính luôn luôn có nhiều nhất
là 1 tiến trình trong đoạn găng – đây là một thuộc tính an toàn cơ bản
a Bất biến (Invariants)
Trong thực tế, thuộc tính safety ở trên là một trường hợp cụ thể của invariants
Bất biến là những thuộc tính thời gian tuyến tính được định nghĩa bởi 1 điều kiện Φ cho các trạng thái và yêu cầu Φ giữ tất cả các trạng thái có thể đạt được
Lưu ý rằng:
khi và chỉ khi với tất cả đường dẫn π trong TS khi và chỉ khi với tất cả trạng thái s thuộc một đường dẫn của TS
Khái niệm “bất biến” có thể giải thích như sau: điều kiện Φ được thoả mãn bởi tất cả các trạng thái ban đầu và tính thoả mãn của Φ là bất biến dưới mọi phép chuyển trong đường dẫn có thể đạt được của hệ thống chuyển Ngoài ra, nếu Φ giữ trạng thái nguồn s của phép chuyển thì Φ cũng sẽ giữ trạng thái đích của phép chuyển
Trang 30dài tối thiểu Tập tất cả các tiền tố xấu của Psafe ký hiệu là BadPref(P safe ), tập hợp tất cả
các tiền tố xấu nhỏ nhất là MinBadPref(P safe )
Định lý 3.13 Mối quan hệ thỏa mãn cho các thuộc tính an toàn (Satisfaction Relation for Safety Properties)
Cho hệ chuyển TS không có trạng thái kết thúc và một thuộc tính an toàn Psafe :
Công thức (3.4) chỉ ra rằng hệ chuyển TS thoả mãn thuộc tính an toàn khi
và chỉ khi không có tiền tố xấu nào của trên các vết có kết thúc của hệ chuyển
TS
3.4.4 Các thuộc tính hoạt động được (liveness properties)
Các thuộc tính được gọi là thuộc tính “hoạt động được”, chúng tuyên bố rằng
“những điều tốt” sẽ xảy ra Trong khi các thuộc tính an toàn bị vi phạm trong thời gian hữu hạn bởi một hệ thống hữu hạn, thì thuộc tính hoạt động được bị vi phạm trong thời gian vô hạn bởi một hệ thống vô hạn
a Thuộc tính hoạt động được
Định nghĩa 3.14 Thuộc tính hoạt động được
Thuộc tính thời gian tuyến tính LT Plive trên AP là một thuộc tính hoạt động được
Vì vậy, một thuộc tính hoạt động được (trên AP) là một thuộc tính thời gian tuyến tính P mà mỗi từ hữu hạn có thể được mở rộng thành một từ vô hạn thỏa mãn P Với các trạng thái khác nhau, P là một thuộc tính hoạt động được khi và chỉ khi tất cả
b So sánh các thuộc tính an toàn và thuộc tính hoạt động được
Phần này nói về mối quan hệ giữa thuộc tính an toàn và thuộc tính hoạt động được Cụ thể là nó sẽ trả lời cho hai câu hỏi sau:
Các thuộc tính an toàn và thuộc tính hoạt động được có tách rời nhau không? Một thuộc tính thời gian tuyến tính bất kỳ là thuộc tính an toàn hay thuộc tính hoạt động được?
Với câu hỏi đầu tiên, các thuộc tính an toàn và thuộc tính hoạt động được thực sự
là tách rời nhau Nói một cách chính xác hơn thì nó chỉ ra rằng một thuộc tính có cả hai tính chất là an toàn và hoạt động được là rất hạn chế
Câu hỏi thứ hai là kết quả trong một câu trả lời phủ định Với bất kỳ thuộc tính thời gian tuyến tính P nào cũng sẽ có một thuộc tính thời gian tuyến tính P’ tồn tại một
sự kết hợp (như là phép giao) của một thuộc tính an toàn và một thuộc tính hoạt động được
Định lý 3.15 Giao của các thuộc tính an toàn và các thuộc tính hoạt động được
Trang 31Chỉ có duy nhất một thuộc tính LT trên AP vừa là thuộc tính an toàn và vừa là thuộc tính hoạt động được là
3.4.5 Sự công bằng (fairness)
Một khía cạnh quan trọng của hệ phản vệ là sự công bằng Các giả định công bằng loại bỏ các hành vi vô hạn mà được xem xét một cách không thực tế, và thường cần để chứng minh các thuộc tính hoạt động được
a Các ràng buộc công bằng (Fairness Constraints)
Thông thường, một thực thi công bằng (hay một vết) là được mô tả bởi một thực tế là các ràng buộc công bằng phải được thỏa mãn Ràng buộc công bằng thường được dùng để loại bỏ các tính toán được đánh giá là vô lý với hệ thống đang xem xét Các ràng buộc công bằng được xem xét dưới các khía cạnh sau: Công bằng vô điều kiện (unconditional fairness)
Công bằng mạnh (strong fairness)
Công bằng yếu (Weak fairness)
Định nghĩa 3.16 Công bằng (A-fair ) vô điều kiện, mạnh và yếu
Với hệ chuyển TS = (S, Act, →, I, AP, L) không có trạng thái kết thúc,
1 là A-fair vô điều kiện khi và chỉ khi (3.5)
2 là A-fair mạnh khi và chỉ khi
và hành động trong tập hành động A là luôn luôn thực hiện được
Công thức (3.6) nói rằng một công bằng là mạnh khi vào chỉ khi tồn tại giá trị j trên tập hành động của trạng thái sj giao với tập trạng thái A thì tồn tại hành động trong tập hành động A sẽ thực thi được
Công thức (3.7) nói rằng một công bằng là yếu khi vào chỉ khi hầu như mọi giá trị j trên tập hành động của trạng thái sj giao với tập trạng thái A thì tồn tại hành động trong tập hành động A sẽ thực thi được
Trang 32Mối quan hệ giữa các loại công bằng là mỗi công bằng vô điều kiện là bao hàm công bằng mạnh, mỗi công bằng mạnh là bao hàm một công bằng yếu Ví dụ một đường thực thi là công bằng mạnh, nhưng nó không phải là một công bằng vô điều kiện, còn một công bằng vô điều kiện thì chắc chắn là một công bằng mạnh Chiều ngược lại không đúng
Công bằng vô điều kiện => Công bằng mạnh => Công bằng yếu
Định nghĩa 3.17 Giả định công bằng (Fairness Assumption)
Một giả định công bằng cho tập hành động Act là một bộ
Nó là một A-fair vô điều kiện với tất cả ,
Nó là một A-fair mạnh với tất cả , và
Nó là một A-fair yếu với tất cả ,
Nếu tập là rỗng trong trường hợp này, chúng ta dùng khái niệm công bằng (fair) thay cho
b Tính công bằng và tính an toàn
Trong khi giả định công bằng là cần thiết để kiểm tra các thuộc tính hoạt động được, chúng lại không thích hợp để kiểm tra các thuộc tính an toàn, bởi vì chúng luôn đảm bảo rằng có một chiến lược lập lịch thích hợp Bởi vậy các giả định công bằng được gọi là các giả định công bằng có thể nhận thức được Một giả định công bằng không thể nhận thức được trong một hệ chuyển khi tồn tại một trạng thái có thể đạt được tại chỗ mà đường dẫn không công bằng bắt đầu Trong trường hợp này, không thể thiết kế một bộ lịch biểu để giải quyết vấn đề không đơn định như khi chỉ có các đường dẫn công bằng còn lại
Định nghĩa 3.18 Giả định công bằng có thể nhận thức được (Realizable Fairness Assumption)
TS là một hệ chuyển với một tập các hành động Act và là một giả định công bằng cho tập Act được gọi là có thể nhận thức được trong TS nếu với mỗi trạng thái
đạt được s phải khác rỗng ta có:
Trang 333.4.6 Logic thời gian tuyến tính (Linear temporal logic - LTL)
a Cú pháp của LTL
Theo [10], LTL dựa trên các phép toán mệnh đề; công thức của các phép toán mệnh đề bao gồm các mệnh đề nguyên tử (ký hiệu bởi các chữ cái p, q…) và các phép toán như trong bảng 3.1
Theo [10], một công thức của LTL được xây dựng từ các mệnh đề nguyên thủy
và từ các toán tử bao gồm các toán tử của các phép toán mệnh đề cũng như các toán tử thời gian Các toán tử thời gian được mô tả trong bảng 3.2
Bảng 3.2 Các toán tử thời gian trong LTL
Phép toán Ký hiệu trong SPIN
Luôn luôn (always) Tồn tại (eventually) Cho đến khi (until)
Toán tử luôn luôn và tồn tại là toán tử 1 ngôi, và toán tử cho đến khi là toán tử hai ngôi Toán tử thời gian và toán mệnh đề được kết hợp tự do Ví dụ như trong công thức sau: công thức này được đọc là luôn luôn có p giao với q, kéo theo là r giữ cho đến khi (p hoặc q) giữ
Trang 34Ví dụ critical là giá trị của một biến critical trong một chương trình về đoạn găng; biểu thức critical <= 1 là một mệnh đề nguyên tử, bởi vì nó có thể được gán giá trị đúng trong một trạng thái s bằng việc kiểm tra giá trị của biến critical trong trạng thái s
3.5 Các công cụ kiểm chứng mô hình
Từ khi kiểm chứng mô hình bắt đầu được phát triển cho đến nay, có rất nhiều công cụ để kiểm chứng mô hình Theo thống kê của trang web
http://anna.fi.muni.cz/yahoda/ (trang được xây dựng và cập nhật bởi phòng thí nghiệm ParaDiSe của khoa Thông tin, đại học Masaryk University Brno, cộng hòa Séc) đến tháng 9/ 2012, khoa đã thống kê được 68 công cụ kiểm chứng trong đó có 53 công cụ kiểm chứng mô hình Trong đó, chúng ta có thê kể đến một số công cụ phổ biến như là SPIN, NuSMV, Java Pathfinder, KRONOS
SPIN (Simple Promela Interpreter – Trình biên dịch Promela đơn giản) là công
cụ hỗ trợ cho việc kiểm chứng mô hình cho các hệ phân tán Phần mềm này được phát triển bởi phòng thí nghiệm Bell Labs trong nhóm các phương pháp hình thức và kiểm chứng bắt đầu từ năm 1980 SPIN cùng với ngôn ngữ Promela là một bộ công cụ mạnh
mẽ, và được áp dụng rộng rãi trong kỹ thuật kiểm chứng mô hình
NuSMV (A new symbolic model checker – bộ kiểm chứng mô hình biểu tượng mới) có ngôn ngữ đầu vào được thiết kế để cho phép mô tả các hệ thống hữu hạn trạng thái Mục đích cơ bản của ngôn ngữ NuSMV là mô tả (sử dụng các biểu thức trong các phép tính mệnh đề) phép chuyển liên quan tới cấu trúc hữu hạn Kripke
Java Pathfinder (JPF) là một hệ thống đánh giá các chương trình thực thi của Java bytecode Java được phát triển bởi trung tâm nghiên cứu NASA và trở thành mã nguồn mở năm 2005
KRONOS là một công cụ kiểm chứng mô hình với thời gian phân nhánh (branch time) và kiểm chứng tương đương dùng cho ngôn ngữ mô hình hóa Timed Automata Trong KRONOS, các thành phần của hệ thống thời gian thực được mô hình hoá thành các automat thời gian, và các yêu cầu chính xác được biểu diễn trong logic thời gian thực TCTL (TCTL là một mở rộng của logic thời gian CTL – Computation Tree
Trang 35Logic– Logic cây tính toán mà cho phép định lượng lý luận thời gian trên một khoảng thời gian liên tục
Mỗi công cụ kiểm chứng đều có những ưu nhược điểm khác nhau, và được áp dụng trong những bài toán cụ thể Luận văn lựa chọn SPIN là công cụ kiểm chứng bởi
vì SPIN được ứng dụng rộng rãi trong việc kiểm chứng các hệ phân tán cả trong nghiên cứu và trong công nghiệp, có tính phổ quát, dễ ứng dụng, cộng đồng phát triển
và nghiên cứu hoạt động tích cực và ngôn ngữ mô hình hóa PROMELA gần với ngôn ngữ lập trình C
Trang 36Chương 4 Ngôn ngữ Promela và công cụ kiểm
chứng mô hình SPIN
Công cụ kiểm chứng mô hình SPIN là một công cụ được áp dụng rộng rãi trong nghiên cứu khoa học và trong công nghiệp Ngôn ngữ Promela là ngôn ngữ để mô hình hóa hệ thống phần mềm để công cụ SPIN có thể hiểu và kiểm chứng mô hình cho
bộ hoặc không đồng bộ
Mô hình SPIN có 3 loại đối tượng: các tiến trình (processes), các kênh thông điệp (message channels), và các biến (variables) Các tiến trình là các đối tượng toàn cục Các kênh thông điệp và các biến là các dối tượng có thể được khai báo toàn cục hoặc cục bộ Các tiến trình đặc tả hành vi, các kênh và biến toàn cục định nghĩa môi trường
mà trong đó các tiến trình chạy
4.1.1 Kiểu dữ liệu, toán tử và câu lệnh
a Kiểu dữ liệu
Theo [10], kiểu dữ liệu của ngôn ngữ Promela được mô tả như trong bảng 4.1
Bảng 4.1 Kiểu dữ liệu số của Promela
Unsigned
Trang 37Ngoài ra thì Promela còn cung cấp các kiểu dữ liệu khác là: chan (kiểu kênh),
Promela không cung cấp kiểu ký tự (char), kiểu chuỗi (string) và kiểu dấu phẩy động (floating-point number) Ký tự có thể gán cho biến với kiểu byte và được ghi
ra theo cấu trúc %c Kiểu chuỗi là không cần thiết trong Promela do cần tối giản hóa chương trình, và từ khóa printf chỉ có tác dụng khi mô hình hóa chương trình, còn
khi SPIN chứng minh chương trình thì không gọi đến nó Kiểu dấu phẩy động có thể được sử dụng bằng cách nhúng các mã lệnh C vào trong chương trình
b Toán tử và biểu thức
Theo [10], một tập các toán tử trong Promela được định nghĩa như trong Hình 4.1 Các toán tử này được mô tả tương tự như ngôn ngữ C Có một điểm cần lưu ý là các toán tử này là vô hướng (side-effect free), và chỉ có các hậu tố trong phép toán
chứ không có các tiền tố Ví dụ: ta chỉ có thể biểu diễn là:
a = b++ là đúng
a = ++b là sai
Hình 4.1 Các toán tử trong ngôn ngữ Promela
Các định danh biểu tượng (Symbolic names) được dùng để khai báo một biểu
tượng cho một số, một marco tiền xử lý có thể được dùng ở đầu chương trình
# define max 10
Kiểu mtype (message type – kiểu thông điệp) được dùng để khai báo các định danh bộ nhớ cho các giá trị Ưu điểm của mtype là các giá trị biểu tượng có thể được
Trang 38in ra theo cấu trúc %e, và sau đó chúng sẽ xuất hiện trong phần lần vết (traces) của chương trình Nhược điểm của mtype là nó chỉ có một tập các tên đã định nghĩa trước cho toàn bộ chương trình Giá trị mtype có thể được in ra bằng lệnh printm
Trong Promela thì câu lệnh điều kiện được định nghĩa bằng cặp từ khóa if và
fi, cùng với cặp dấu hai chấm (::) định nghĩa điều kiện trong chương trình Từ khóa
skip được dùng để thoát ra khỏi chương trình khi mà biểu thức đánh giá luôn có giá trị true hoặc (1)
d Câu lệnh lặp do
Chỉ có một loại câu lệnh lặp trong Promela là câu lệnh do Câu lệnh lặp do được
khai báo tương tự như câu lệnh điều kiện if
e Câu lệnh nhảy jump
Promela cung cấp các câu lệnh nhảy đến một phần khác trong chương trình là
nhưng lệnh nhảy goto cần được chỉ định là sẽ nhảy đến phần nào của chương trình bằng một nhãn (label), còn lệnh break chỉ đơn giản là thoát ra khỏi vòng lặp
4.1.2 Dữ liệu và cấu trúc chương trình
a Kiểu mảng (array)
Tương tự như các ngôn ngữ lập trình khác, Promela cũng có dữ liệu kiểu mảng (array) Mảng trong Promela là mảng một chiều, muốn khai báo mảng hai chiều thì chúng ta cần dùng cách khác để thực hiện Cấu trúc và ngữ nghĩa của mảng tương tự như trong ngôn ngữ lập trình C
Trang 39Các phần tử của mảng được khai báo tuần tự như sau:
Int Array[4];
Array[0] = 3; Array[1] = 12; Array[2] = 14; Array[3] = 32;
Mảng của các dữ liệu kiểu bit hay bool sẽ được lưu trong mảng kiểu byte, để tiết kiệm bộ nhớ thì các kiểu dữ liệu khác cũng có thể lưu trong mảng kiểu byte bằng
cách dịch chuyển bit (shift) và dùng mặt nạ (mask)
b Định nghĩa kiểu (type definitions)
Các kiểu kết hợp được định nghĩa với typedef và thường được dùng để định
nghĩa cấu trúc của các thông điệp được gửi qua các kênh:
typedef MESSAGE { mtype message;
byte source;
byte destination;
bool urgent
} Kiểu tự định nghĩa này cũng được dùng để khai báo mảng 2 chiều trong Promela
Cú pháp của kiểu tự định nghĩa này tương tự với các ngôn ngữ giống C
c Bộ tiền xử lý (The preprocessor)
SPIN được cài đặt bằng ngôn ngữ C, nên nó cũng có những đặc tính tương tự C
Nó sử dụng một công cụ biên dịch được gọi là bộ tiền xử lý – nó sẽ được gọi trước khi
bộ biên dịch thực thi Bộ tiền xử lý cũng được dùng để dẫn dắt quá trình xử lý các macro dựa vào văn bản (text-based) trên mã nguồn Dựa vào văn bản có nghĩa là bộ tiền xử lý không có bất kỳ tri thức nào về cú pháp và ngữ nghĩa của ngôn ngữ, thay vào đó là xem mã nguồn như là văn bản thuần
Khi SPIN chạy ở bất kỳ mode nào, nó cũng gọi bộ tiền xử lý trước tiên, thông thường thì nó sẽ giống như là bộ tiền xử lý được kết hợp với bộ biên dịch dùng để biên dịch các bộ kiểm chứng
Chúng ta có thể gặp các bộ tiền xử lý như #define, #include, và inline
tương tự như ngôn ngữ C trong SPIN
#define N 5 // Định nghĩa một ký hiệu, nhãn
// được dùng trong các đặc tả tính // đúng đắn
Ngoài ra bộ tiền xử lý còn được cài đặt, ứng dụng trong việc biên dịch điều kiện (condition compilation), và các macro