Luận văn Phát triển các kỹ thuật tìm bất biến (Invariants) và biến (Variants) cho việc sử dụng Hoare logic để chứng minh tính đúng đắn của chu trình

Các kết quả nghiên cứu về đề tài chứng minh tính đúng đắn của chu trình bằng logic Hoare không phải là mới nhưng thực sự nó vẫn còn mang tính thời sự. Việc áp dụng vào thực tế trong việc chứng minh tính đúng của chương trình góp phần quan trọng để đảm bảo một chương trình thỏa mãn yêu cầu lập trình. Trong phần luận văn tôi đã cố gắng dẫn dắt những kiến thức theo một logic hợp lý và trực quan nhất. Những lý thuyết cơ bản và bài toán ví dụ được đưa ra xen kẽ và liên tục (từ chương 2 đến chương 4) với mục đích không chỉ là cung cấp lý thuyết mà còn đem lại cho bản thân cũng như người đọc một vài kinh nghiệm rút ra trong việc tìm biến và bất biến để chứng minh tính đúng đắn của lệnh chu trình. Những kiến thức của phần luận văn có thể được tổng hợp một cách vắn tắt như sau: Đầu tiên là những kiến thức tổng quan về logic vị từ, logic Hoare; Các kỹ thuật chứng minh tính đúng của lệnh chu trình bằng phương pháp logic Hoare kèm vào đó là các ví dụ minh họa chi tiết cho việc chứng minh; Làm rõ hơn về biến và bất biến, đi xâu vào tìm hiểu về bất biến vòng lặp, các ví dụ minh họa được thể hiện trên một vài thuật toán cơ bản nhất; Cuối cùng các kinh nghiệm rút ra từ việc nghiên cứu trong quá trình thực hiện tìm biến, bất biến trên các ví dụ bài toán vòng lặp cụ thể. Trên thực tế có nhiều công cụ tự động trong việc chứng minh tính đúng đắn của chương trình, tuy nhiên hiểu rõ phương pháp chứng minh, hiểu rõ bản chất của vòng lặp luôn làm cho người lập trình ít mắc sai sót trong quá trình viết code. Khi đó, chương trình được viết ra sẽ đảm bảo chạy đúng và ổn định hơn. Nó góp phần giảm thiểu rủi ro và kinh phí sửa chữa, bảo trì. Qua quá trình nghiên cứu về luận văn, bản thân tôi đã lĩnh hội được một lượng kiến thức khá lớn từ đó đã làm rõ những ưu tư, thắc mắc của mình trong quá trình giảng dạy bộ môn tin học tại cấp độ THPT. Đó là những kiến thức liên quan đến tính đúng đắn của chương trình, đến bản chất của vòng lặp, đến tính kết thúc Thực sự rất là hữu ích trong việc giảng dạy học sinh lớp 10 (trong các bài liên quan đến thuật toán), học sinh lớp 11 (giảng dạy về ngôn ngữ lập trình, Pascal).

pdf66 trang | Chia sẻ: yenxoi77 | Lượt xem: 609 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Luận văn Phát triển các kỹ thuật tìm bất biến (Invariants) và biến (Variants) cho việc sử dụng Hoare logic để chứng minh tính đúng đắn của chu trình, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
trình bày ở trên trong quá trình vòng lặp là nó làm nổi bật bản chất của bất biến: Nó là một dạng tổng quát của hậu điều kiện mong muốn, mà trong một trường hợp đặc biệt (đại diện bởi các điều kiện thoát vòng lặp) sẽ cho tôi hậu điều kiện đó. Quan điểm này của bất biến, như là một cách đặc biệt trong khái quát các mục tiêu mong muốn của việc tính toán vòng lặp, giải thích lý do tại sao bất biến vòng lặp là một tài sản quan trọng như vậy của các vòng lặp; ai có thể tranh luận rằng sự hiểu biết một vòng lặp có nghĩa là sự hiểu biết bất biến của nó (mặc dù các quan sát rõ ràng rằng nhiều người lập trình viết các vòng lặp mà gần như chưa bao giờ chính thức học qua khái niệm bất biến, mặc dù tôi có thể khẳng định rằng nếu họ hiểu những gì họ đang làm họ đang dựa vào một số hiểu biết trực giác về bất biến, như ông Jourdain Moli`ere đã nói). 4.2.3 Ví dụ cơ bản Để minh họa cho ý tưởng trên, tôi áp dụng trong thuật toán tìm ước chung lớn nhất của 2 số nguyên dương a và b. Thuật toán như sau: while a khác b do nếu a>b thì a:=a-b ngược lại b:=b-a; Uoc chung lon nhat la: a; Khi đó, Hậu điều kiện của bài toán là: Result = UC(a, b) Trong trường hợp các số nguyên dương a và b là các đầu vào và UC là hàm toán học tính ước số chung lớn nhất. Tôi có thể viết tổng quát như sau: Result = x  UC(Result, x) = UC(a,b) Với mỗi biến x mới, bằng các tính chất toán học, với mọi x, tôi có UC(x,x) = x 29 Do vậy, tôi có được các thành phần của bất biến là: Result >0 và x > 0 UC (Result, x) = UC (a, b) Những liên kết thứ hai, một sự tổng quát của hậu điều kiện, sẽ được sử dụng như là bất biến; các liên kết đầu tiên sẽ sử dụng như là điều kiện thoát vòng lặp. Để có được thân vòng lặp, áp dụng đặc tính phương pháp toán học tìm ước chung lớn nhất, tôi có: với mọi x > y thì UC (x, y) = UC (x-y, y) với mọi x < y thì UC (x, y) = UC (x, y-x) Tôi thể hiện thuật toán với bất biến vòng lặp như sau: 1 from 2 Result := a ; x := b 3 invariant 4 Result >0 5 x > 0 6 UC (Result, x) = UC (a, b) 7 until 8 Result = x 9 loop 10 if Result > x then 11 Result := Result − x 12 else /*Ở đây giá trị của x sẽ lớn hơn Result*/ 13 x := x − Result 14 end 15 variant 16 max (Result, x) 17 end Hình 4. 2. Ước số chung lớn nhất của hai số nguyên dương a và b o Các bất biến cần thiết là bất biến bảo toàn. Nó thể hiện rằng một số lượng nhất định vẫn còn tương đương với giá trị ban đầu của nó. o Các chiến lược dẫn đến bất biến bảo toàn này là tách cặp, thay thế thuộc tính của một biến (Result), được sử dụng trong các hậu điều kiện, bằng một thuộc tính của hai biến (Result và x), được sử dụng trong bất biến. 30 4.2.4 Phân loại bất biến: Bất biến vòng lặp có thể được chia theo hai hướng: o Bởi vai trò của nó đối với các hậu điều kiện, giúp tôi phân biệt giữa tính bất biến "cốt lõi" (“essential”) và "chặn" (“bounding”). o Bằng các kỹ thuật chuyển đổi đó mang lại các bất biến từ hậu điều kiện. Ở đây tôi có kỹ thuật như tách cặp (uncoupling) và giảm dư hằng (constant relaxation). 4.2.4.1 Phân loại theo luật Trong chiến lược lặp điển hình được mô tả trong phần 4.1.2, vấn đề cần thiết đó là việc lặp đi lặp lại liên tiếp của thân vòng lặp duy trì trong các vùng hội tụ nơi dạng thức tổng quát của hậu điều kiện được xác định. Các điều kiện tương ứng, tạo nên bất biến chặn; các mệnh đề mô tả hậu điều kiện tổng quát là bất biến cốt lõi. Các bất biến chặn áp dụng cho thuật toán tìm ước số chung lớn nhất bao gồm các mệnh đề: Result > 0 x > 0 Mệnh đề quan trọng là: UC(Result, x) = UC(a, b) Cho kết quả hậu điều kiện nếu Result = x. Đối với các chương trình tìm số lớn nhất trong mảng một chiều, bất biến chặn là: a.lower ≤ i ≤ a.upper và bất biến cốt lõi là: Result = max (a [a.lower.. i] ) Cho kết quả hậu điều kiện khi i = a.upper. Lưu ý rằng bất biến cốt lõi sẽ không được định nghĩa nếu không có bất biến chặn, vì a [1 .. i] sẽ chưa được xác định (nếu i> a.upper) hoặc sẽ là trống rỗng và không lớn nhất (nếu i <a.lower ). Đối với các chương trình tối đa hai chiều, bất biến chặn là: a.lower ≤ i ≤ j ≤ a.upper và bất biến cốt lõi là: max(a) = max(a[i..j]) Cho kết quả các hậu khi i = j. Một lần nữa, bất biến cốt lõi sẽ không luôn luôn được xác định mà không có bất biến chặn. 31 Việc tách biệt giữa bất biến chặn và bất biến cốt lõi thường là đơn giản như trong các ví dụ. Trong trường hợp nghi ngờ, các quan sát sau đây sẽ giúp phân biệt. Các chức năng tham gia vào bất biến thường là một phần; ví dụ: o UC (u, v) được xác định nếu u và v đều khác không (và, vì tôi xem xét các số nguyên tự nhiên duy nhất trong ví dụ, tích cực). o Đối với mảng a và một số nguyên i, a [i] được xác định nếu  . .. .i a lower a upper và a [i .. j] là khác rỗng chỉ khi    .. . .. .i j a lower a upper . o Max (a) được chỉ định nếu các mảng a là không trống rỗng. 4.2.4.2 Phân loại theo kỹ thuật khái quát hóa Các bất biến cốt lõi là một đột biến (thường là một sự suy yếu) của hậu điều kiện vòng lặp. Các kỹ thuật đột biến sau đây là đặc biệt phổ biến: Giảm dư hằng: thay thế một hằng số n (thường hơn, một biểu hiện mà không thay đổi trong quá trình thực hiện các thuật toán) bằng một biến i, và sử dụng i = n như là một phần hoặc tất cả các điều kiện thoát. Giảm dư hằng là kỹ thuật được sử dụng trong việc tính toán giá trị lớn nhất của mảng một chiều, nơi hằng số là giới hạn trên của mảng. Các bất biến khái quát các hậu điều kiện "Result là lớn nhất của mảng cho tới a.lower", nơi a.lower là một hằng số, "Result là lớn nhất cho tới i". Điều kiện này là tầm thường để cho những thiết lập ban đầu của một mảng không rỗng (lấy i thay thế a.lower), dễ dàng mở rộng để tăng giá trị của i lên (lấy Result là lớn hơn giá trị trước đó của nó và a [i]), và kết quả là hậu điều kiện khi i đạt đến a. upper. Tìm kiếm nhị phân khác với tìm kiếm tuần tự bằng cách áp dụng giảm dư hằng, cho cả các giới hạn trên và dưới của mảng. Trong phần 3.2 các ví dụ chứng minh, tôi cũng đã áp dụng kỹ thuật giảm dư hằng trong công việc tìm bất biến vòng lặp. Đối với bài toán 1, hậu điều kiện là 1 n j Q s j          với n là hằng số giới hạn trên của khoản giá trị của biến chỉ số vòng lặp. Khi đó việc thay thế n bằng biến i là một tính toán dễ hiểu nhằm làm cho hậu điều kiện phụ thuộc vào chỉ số của vòng lặp. Bằng một vài tính toán khác nhằm phù hợp với bài toán tôi có được bất biến như mong muốn. Bài toán thứ 2, hậu điều kiện là  mr n việc thay thế hằng số m cũng được thực hiện tương tự bằng một biến chỉ số vòng lặp là i. Tôi dễ dàng có được một bất biến cốt lõi của vòng lặp là  ir n . 32 Tách cặp: thay thế một biến v (thường Result) bằng hai (trong ví dụ phần 4.1.3 là result và x), sử dụng bình đẳng của chúng như là một phần hoặc là tất cả đối với các điều kiện thoát vòng lặp. Tách cặp được sử dụng trong thuật toán ước số chung lớn nhất. 4.3 Tìm biến và bất biến vòng lặp trong một vài thuật toán cơ bản 4.3.1 Tìm phần tử có giá trị lớn nhất trong một dãy các phần tử 4.3.1.1 Số lớn nhất với vòng lặp một biến Phương pháp max_one_way trả về phần tử tối đa của mảng a (mảng chưa được sắp xếp) trong giới hạn giữa a.lower và a.upper. Giá trị lớn nhất chỉ được xác định áp dụng đối với một mảng có ít nhất một phần tử, do đó các điều kiện tiên quyết . 1a count  . Chương trình cơ bản như sau của thuật toán: Result:=a[a.lower]; i:=a.lower; while i<a.upper do begin i:=i+1; if Result < a[i] then Result:= a[i]; end; Các hậu điều kiện có thể được viết là: Result = max(a) Viết nó ở dạng phần tử mảng, tôi có Result = max (a [a.lower..a.upper]) cho tôi kết quả bất biến của giảm dư hằng trong giới hạn giữa a.lower và a.upper. Tôi chọn một trong hai để thay thế, kết quả được bất biến vòng lặp mong muốn là Result = max(a [ a. lower.. i] ) và a.lower ≤ i ≤ a.upper. Ở đây, tôi đã thay thế i=a.upper Việc tìm biến được thực hiện như sau: Nhận thấy chỉ số của vòng lặp thay đổi trong khoảng giới hạn giữa a.lower và a.upper. Giá trị của i được khởi tạo bắt đầu bằng a.lower, nó liên tục tăng lên đến khi i = a.upper vòng lặp sẽ dừng lại. Giá trị của biến sẽ thay đổi liên tục, qua phân tích ở trên tôi dễ ràng chọn ra được một biến chức năng là a.upper – i , bởi vì với i = a.upper thì a.upper – i = 0 do đó vòng lặp sẽ kết thúc. Khi i 0 đảm bảo phần thân vòng lặp được thực hiện. 33 Hình 4.3 cho thấy việc thực hiện kết quả của thuật toán. 1 max_one_way (a: ARRAY [T]): T 2 require 3 a.count ≥ 1 /*a.count là số lượng phần tử của mảng*/ 4 local 5 i : INTEGER 6 do 7 from 8 i := a.lower ; Result := a [a.lower] 9 invariant 10 a.lower ≤ i ≤ a.upper 11 Result = max (a [a.lower, i]) 12 until 13 i = a.upper 14 loop 15 i := i + 1 16 if Result <a [i] then Result := a [i] end 17 variant 18 a.upper – i +1 19 end 20 ensure 21 Result = max (a) 22 end Hình 4. 3. Số lớn nhất với vòng lặp một biến 4.3.1.2 Số lớn nhất với vòng lặp hai biến Thuật toán số lớn nhất với vòng lặp một biến lựa chọn độc đáo để áp dụng giảm dư hằng là a.lower hoặc (như trong thuật toán phần 4.3.1.1 ở trên) là a.upper. Đối với thuật toán số lớn nhất với vòng lặp hai biến tôi hướng tới một mối quan tâm có tính đối xứng. Tôi có thể chọn một cặp giảm dư hằng. Nếu i và j là hai biến số giảm dư, thân vòng lặp hoặc tăng i, hoặc giảm j. Khi i = j, vòng lặp đã xử lý tất cả các phần tử của mảng a, và vì thế i hoặc j là biến chỉ số cho tôi biết phần tử lớn nhất. Hậu điều kiện có thể được viết là: Result = max(a) 34 Tôi viết nó dưới dạng phần tử mảng Result = max (a [a.lower..a.upper]). Khi được thay thế cặp giảm dư hằng i := a.lower và j := a.upper, tôi được max (a [i..j]). Khi đó tôi chọn được bất biến vòng lặp mong muốn là a.lower ≤ i ≤ j ≤ a.upper và max (a [i..j]) = max (a). Biến được xác định bằng hiệu của hai cặp giảm dư hằng là i – j. Thực vậy khi i = j. Hiệu số sẽ bằng 0 và khi đó vòng lặp sẽ kết thúc. Các đặc tả kỹ thuật (điều kiện tiên quyết và hậu điều kiện) cũng giống như đối với các thuật toán với vòng lặp một biến. Hình 4.4 cho thấy việc thực hiện thuật toán như sau: 1 max_two_way (a: ARRAY [T]): T 2 require 3 a.count ≥ 1 4 local 5 i , j: INTEGER 6 do 7 from 8 i := a.lower ; j := a.upper 9 invariant 10 a.lower ≤ i ≤ j ≤ a.upper 11 max (a [i..j]) = max (a) 12 until 13 i = j 14 loop 15 if a [ i ] > a [ j] then j := j − 1 else i := i + 1 end 16 variant 17 j − i 18 end 19 Result := a [i] 20 ensure 21 Result = max (a) 22 end Hình 4. 4. Số lớn nhất với vòng lặp hai biến. 35 4.3.2 Tìm kiếm 4.3.2.1 Tìm kiếm trong một mảng chưa được sắp xếp Chương trình has_sequential sau đây trả ra vị trí xuất hiện của một phần tử khóa (key) trong một mảng a hoặc, nếu key không xuất hiện, sẽ trả ra một giá trị đặc biệt. Thuật toán áp dụng đối với bất kỳ cấu trúc tuần tự nào nhưng được sử dụng ở đây là cho cấu trúc mảng. Để đơn giản, tôi giả định rằng a.lower (cận dưới của mảng) là 1, với mục đích tôi có thể chọn 0 như là một giá trị đặc biệt. Các đặc điểm kỹ thuật có thể sử dụng các yếu tố ký hiệu miền elements (a) để diễn tả tập các phần tử của một mảng a. Một dạng thức đơn giản của hậu điều kiện là 0 (a)Result key elements   (10) Mà chỉ cần ghi lại xem key đã được tìm thấy. Thay vào đó, tôi sẽ sử dụng một dạng thức có thể ghi lại vị trí các phần tử xuất hiện nếu có: 0 a(Result)Result key   (11) 0 (a)Result key elements   (12) Để cho rõ ràng tôi thêm vào trước các điều khoản ràng buộc  0.. .Result a upper Để làm cho nó rõ ràng rằng các truy cập mảng trong (11) được xác định khi cần thiết. Nếu trong (12) tôi thay thế mảng a bởi  1.. .a a upper , tôi có được bất biến của vòng lặp tìm kiếm tuần tự bằng cách giảm dư hằng: giới thiệu một biến i để thay thế một trong các giới hạn 1 và a.upper. Tôi có được những thành phần của bất biến sau đây: 0 ≤ i ≤ a.count  0,iResult  0Result key a Result     0 1..Result key elements a i   Biến chức năng được xác định như sau: Các phân tích trên cho thấy tăng i liên tục, bắt đầu từ 0 tiến dần tới a.count. Khi i= a.upper vòng lặp sẽ chấm dứt. Tôi đơn giản nhận ra rằng biến được chọn là: t = a.upper – i+1. 1 has sequential (a: ARRAY [T]; key: T): INTEGER 2 require 36 3 a.lower = 1 4 local 5 i: INTEGER 6 do 7 from 8 i := 0 ; Result := 0 9 invariant 10 0 ≤ i ≤ a.count 11  0,iResult 12  0Result key a Result   13   0 1..Result key elements a i   14 until 15 i = a.upper 16 loop 17 i := i + 1 18 if a [i] = key then Result := i end 19 variant 20 a.upper − i + 1 21 end 22 ensure 23  0,a.upperResult 24  0Result key a Result   25  0Result key elements a   26 end Hình 4.5. Tìm kiếm trong một mảng chưa được sắp xếp. 4.3.2.2 Tìm kiếm nhị phân Tìm kiếm nhị phân hoạt động trên các mảng đã được sắp xếp bằng việc lặp đi lặp lại giảm một nửa, một phân đoạn của mảng đó. Tìm kiếm sẽ kết thúc, hoặc khi phần tử key được tìm thấy hoặc khi phân khúc này trở nên trống rỗng, ngụ ý rằng các phần tử không xuất hiện ở một nơi nào trong mảng. 37 Mặc dù ý tưởng cơ bản của tìm kiếm nhị phân là tương đối đơn giản, nhưng khi thực hiện các chi tiết có thể gây ngạc nhiên vì sự khó khăn, và nhiều người lập trình đã làm sai trong vài lần đầu tiên họ cố gắng. Lý luận một cách cẩn thận trên các đặc điểm kỹ thuật (ở cấp lý thuyến miền) và kết quả bất biến nhằm giúp tránh mắc phải những sai lầm. Tôi thấy các hậu điều kiện cũng giống như đối với tìm kiếm tuần tự (mục 4.1.3). Thuật toán và thực hiện bây giờ có điều kiện tiên quyết sorted (a) Sử dụng lý thuyết miền Sorted (a), được định nghĩa là      . ow .. . 1 : 1j a l er a upper a j a j     Định lý miền mà trên đó tìm kiếm nhị phân dựa vào là, đối với bất kỳ giá trị mid nằm trong khoảng [i .. j] (nơi mà i và j là chỉ số giá trị của mảng), và một giá trị key bất kỳ kiểu T (kiểu của các phần tử mảng) :   ..key elements a i j              .. 1.. key a mid key elements a i mid key a mid key elements a mid j                (13) Công thức (13) không đối xứng đối với i và j; một phiên bản đối xứng là khả thi, sử dụng trong các phân đoạn, "≥" hơn là ">" và mid hơn là mid + 1. Các mẫu ở (13) có lợi thế của việc sử dụng hai điều kiện loại trừ lẫn nhau trong so sánh các key với a [mid]. Kết quả là, tôi có thể giới hạn trong mảng a giá trị mid được chọn trong [i .. j - 1] (chứ không phải là [i .. j]) từ phân đoạn đầu tiên không liên quan j và các phân đoạn thứ hai có thể không giữ cho mid = j ( a [mid + 1..j] sau đó rỗng). Tất cả những quan sát và lựa chọn ra những kết quả trực tiếp trên văn bản chương trình, nhưng được xử lý tốt hơn các mức đặc điểm kỹ thuật (lý thuyết). Tôi sẽ bắt đầu cho sự đơn giản với phiên bản (10) của hậu điều kiện mà chỉ ghi key xuất hiện hay không xuất hiện, lặp đi lặp lại ở đây để dễ tham khảo: 0 (a)Result key elements   (14) Nhân đôi phía bên tay phải của (14), viết a trong lát tạo thành a [1 .. a.upper], và áp dụng giảm dư hằng hai lần, đến hạn dưới 1 và giới hạn trên a.upper, các thuộc tính của bất biến bất biến cần thiết: 38    (a .. )key elements i j key elements a   (15) Với bất biến chặn 1 .i mid j a upper    Trong đó kết hợp các giả định trên mid cần thiết để áp dụng (13) - cũng thừa nhận trong (15) - và các kiến thức bổ sung 1 i và .j a upper . Cốt lõi của phần trình bày này là: - Hai mệnh đề key ≤ a [mid] và key> a [mid] của (13) là những điều kiện bổ sung dễ kiểm tra, cho thấy một thân vòng lặp bảo tồn bất biến bằng cách kiểm tra key đối với a [mid] và đi sang trái hoặc phải như là kết quả của việc kiểm tra. - Khi i = j, trường hợp phục vụ như là điều kiện thoát, phía bên trái của sự tương đương (15) giảm đến key = a [mid]; Đánh giá biểu thức này cho tôi biết liệu key đã xuất hiện ở tất cả trong toàn bộ mảng, các thông tin tôi tìm kiếm. Ngoài ra, tôi có thể có được hậu điều kiện mạnh mẽ hơn, (11) - (12), trong đó cung cấp Result giá trị chính xác, bởi đơn giản là gán chỉ số mid với Result. Những điều trên đây được thể hiện trong thuật toán hình 4.6: 1 has binary (a: ARRAY [T]; key: T): INTEGER 2 require 3 a.lower = 1 /*Để thuận tiện, xem phần phân tích tìm kiếm tuần tự.*/ 4 a.count > 0 5 sorted (a) 6 local 7 i , j, mid: INTEGER 8 do 9 from 10 i:= 1; j := a.upper; mid :=0; Result := 0 11 invariant 12 1 ≤ i ≤ mid≤ j ≤ a.upper 13    (a .. )key elements i j key elements a   14 until 15 i = j 16 loop 17 mid := i + (j − i)//2 18 if a [mid] < key then i := mid +1 else j := mid end 39 19 variant 20 j − i 21 end 22 if a [mid] = key then Result := mid end 23 ensure 24 0 Result n  25 0Result key a Result     26  0Result key elements a   27 end Hình 4. 6. Tìm kiếm nhị phân 4.3.3 Sắp xếp Một số thuật toán quan trọng sắp xếp một mảng dựa trên so sánh cặp và hoán đổi các phần tử. Các ký hiệu miền thuyết sau đây sẽ hữu ích cho mảng a và b: - Perm (a, b) thể hiện rằng mảng là một hoán vị của nhau (các tính chất của chúng đều giống nhau). - Sorted (a) thể hiện rằng các phần tử mảng xuất hiện trong thứ tự tăng dần:      . ow .. . 1 : 1i a l er a upper a i a i     . Các thuật toán sắp mảng ở đây, có các đặc điểm kỹ thuật: sort (a: ARRAY [T]) require a.lower = 1 a.count = n ≥ 1 ensure perm (a, old a) sorted (a) Bài toán sắp xếp kiểu nổi bọt (Bubble sort) Là một phương pháp sắp xếp khá phổ biến, Bubble sort được biết đến không phải là do hiệu quả làm việc của nó mà chỉ bởi vì nó đơn giản. Nó dựa trên ý tưởng của sự đảo ngược: một cặp phần tử chưa được sắp xếp sẽ được đảo ngược 40 thành một cặp phần tử được sắp xếp nếu mà phần tử đầu tiên lớn hơn phần tử thứ hai. Các quan sát đơn giản cho tôi thấy một mảng được sắp xếp nếu và chỉ nếu nó không còn có sự đảo ngược. Điều đó đưa đến gợi ý để sắp xếp một mảng bằng cách lặp đi lặp lại việc loại bỏ tất cả các hoán đổi. Bất biến trong trường hợp này được rút ra từ hậu điều kiện (Điều đó giống như các thuật toán sắp xếp khác). Hậu điều kiện perm(a, old a) với các yếu tố không thay đổi, cũng là một bất biến của hai vòng lặp lồng nhau được sử dụng trong Bubble sort. Các hậu điều kiện khác sorted(a) được thay vì suy yếu, nhưng theo một cách khác nhau hơn so với các thuật toán sắp xếp khác trước đó. Tôi giới thiệu một cờ swapped kiểu Boolean, trong đó ghi lại nếu có một số đảo ngược đã được gỡ bỏ bằng cách hoán đổi một cặp phần tử. Khi swapped là false sau khi quét toàn bộ các phần tử của mảng a, không có đảo đã được tìm thấy, và do đó a đã được sắp xếp. Do đó, tôi sử dụng ws apped như điều kiện thoát của các vòng lặp chính. Hậu điều kiện  w ors apped s ted a  (16) Là bất biến vòng lặp cốt lõi của thuật toán. Các vòng lặp bên thực hiện việc quét mảng đầu vào so sánh tất cả các cặp phần tử liền kề sau đó hoán đổi chúng khi chúng có đảo ngược. Thực hiện việc quét tiến tuyến tính từ phần tử đầu tiên đến người cuối cùng, tôi có được một bất biến cần thiết cho vòng lặp bên trong bằng cách thay thế n bởi i trong (16) viết bằng dạng slice:  w 1..s apped sorted a i    (17) Bất biến chặn 1 ≤ i ≤ n và bất biến vòng ngoài là mệnh đề perm(a, old a) hoàn thành bất biến vòng lặp bên trong. Được thể hiện trong thuật toán (hình 4.7). Các vòng lặp bên trong, đặc biệt, thiết lập swapped thành True bất cứ khi nào nó tìm thấy một số đảo ngược trong khi quét. Điều này báo hiệu rằng việc quét các phần tử của mảng là cần thiết trước khi mảng chắc chắn được sắp xếp. Xác minh tính đúng đắn của chương trình chú thích trong hình 4.7 là dễ dàng, bởi vì bất biến vòng lặp cốt lõi (16) và (17) là hiển nhiên đúng trong tất cả các lần lặp lại nơi swapped được thiết lập là True. Tôi nhận thấy, vòng lặp thực sự kết thúc khi chỉ số của mảng tăng lên đến n, đồng nghĩa với việc quét hết các phần tử của mảng, điều đó được thực hiện trong vòng lặp trong. Khi đó tôi chọn được một biến đối với vòng lặp trong là: n- i, giá trị của hiệu số sẽ về 0 khi i chạy đến n. Đối với vòng lặp ngoài, khi không còn sự hoán đổi nào được tìm thấy vòng lặp sẽ chấm dứt. 41 1 bubble sort basic (a: ARRAY [T]) 2 require 3 a.lower = 1 ; a.count = n ≥ 1 4 local 5 swapped: BOOLEAN 6 i : INTEGER 7 do 8 from swapped := True 9 invariant 10 perm (a, old a) 11  w ors apped s ted a  12 until ws apped 13 loop 14 swapped := False 15 from i := 1 16 invariant 17 1 ≤ i ≤ n 18 perm (a, old a) 19   w or 1..s apped s ted a i  20 until i = n 21 loop 22 if a [ i ] > a [ i + 1] then 23 a.swap (i, i + 1) *Hoán đổi các phần tử ở vị trí i và i+1*/ 24 swapped := True 25 end 26 i := i + 1 27 variant n − i end 28 variant |inversions (a) | 29 end 30 ensure 31 perm (a, old a) 32 sorted (a) 33 end Hình 4. 7. Sắp xếp kiểu nổi bọt. 42 4.4 Ứng dụng kinh nghiệm để tìm biến, bất biến trong một số bài toán. Từ tất cả những kiến thức và bài toán đã trình bày, tôi đã cố gắng tập hợp phân tích nhằm đưa ra những cái nhìn có hướng tổng quan nhất về biến và bất biến của vòng lặp. Sau đây tôi sẽ thử áp dụng những kiến thức có được để làm một số bài toán. Các bài toán được trình bày sau đây được trình bày theo logic đầu tiên là dự đoán biến và bất biến của vòng lặp, sau đó tôi chứng minh biến và bất biến được dự đoán là đúng. Bài 1. Cho chương trình (tựa mã) sau j:=1; k:=1; While j<n do j:= j + 1; k:= k * j; end Hãy tìm biến (t) và bất biến (I) để chứng minh tính đúng đắn của chương trình. Giải: Tôi dự đoán biến và bất biến cho chương trình trên Biến Tôi nhận ra biến chỉ số của vòng lặp là j. Trường hợp này trong điều kiện lặp chỉ với một chỉ số. Giá trị của j thay đổi trong khoảng 1 j n  , Khi j = n vòng lặp sẽ kết thúc. Tôi dự đoán biến t = n – j. Bất biến: Đây là đoạn chương trình tính n!. Hậu điều kiện tổng quát của chương trình là k = n!. Áp dụng kỹ thuật giảm dư hằng tôi thay n bằng biến chỉ số của vòng lặp là j. Khi đó tôi được bất biến cốt lõi là k = j!. Với bất biến chặn là 1 j n  , tôi dự đoán bất biến của vòng lặp là 1 !I j n k j     . Chứng minh biến và bất biến là đúng Biến Đầu tiên tôi chứng minh biến ban đầu là dương, 0b t  đồng nghĩa với 0j n n j    . Điều này được kiểm chứng bằng những logic sau: j n Giả thiết 43 0n j  Chuyển vế Tôi chứng minh sau khi thực hiện thân vòng lặp biến phải giảm giá trị    b t N c t N   đồng nghĩa với việc chứng minh:  j n n j N      1n j N   : * ;k k j   1n j N   : 1j j   n j N  Nhiệm vụ của tôi cần chỉ ra rằng ( 1)j n n j N n j N        . Điều đó được minh chứng bằng những logic sau: n j N  Giả thiết 1n j N   Định nghĩa phép < ( 1)n j N   Quy luật toán học Bất biến Tôi chứng minh sau khi thực hiện thân vòng lặp bất biến được bảo toàn. Với bất biến 1 !I j n k j     , tôi cần chứng minh    b I c I tương đương với việc chứng minh thỏa mãn: {1 !j n k j j n      }  1 1 *( 1) ( 1)!j n k j j       j:=j+1;  1 * !j n k j j    k:=k*j; {1 !j n k j    } Tôi phải cho thấy       1 ! 1 1 * 1 1 !j n k j j n k j j            . Được kiểm chứng bằng những logic sau: 1 1j  Vì 1 j 1j n  Vì j n  *( 1) !* 1k j j j   Vì theo giả thiết !k j b t N  Luật ghép Luật gán t N b I Luật phép gán, ghép Luật phép gán I 44 Kết luận: Bất biến và biến tôi dự đoán là đúng. Bài 2. Cho chương trình (tựa mã) như sau: m := f (1); p := 2; while p ≤ n do if f (p) < m then begin m := f (p); p := p + 1 end end Hãy xác định biến (t) và bất biến (I) đúng để chứng minh tính đúng đắn của chương trình. Bài giải: Tôi dự đoán biến và bất biến như sau : Biến : Tôi nhận thấy đây là vòng lặp thực hiện lặp với một chỉ số trong điều kiện lặp, chỉ số lặp p sẽ tăng lên đến n. Vòng lặp kết thúc khi p vượt quá n. Theo kinh nghiệm đã trình bày ở phần 4.1.2 tôi dự đoán một biến t = n – p + 1. Việc cộng thêm 1 vào hiệu n – p cho tôi một đảm bảo biến t không âm vì p có giá trị lớn nhất là n+1. Ở đầu ra của vòng lặp t = 0. Bất biến : Đoạn mã trên thực hiện bài toán tìm số nhỏ nhất trong một dãy các số có thứ tự từ 1 đến n. Hậu điều kiện tổng quát của chương trình sẽ là “m = min {f(i) | 1 ≤ i ≤ n }”. Sử dụng kỹ thuật giảm dư hằng nhằm mục đích cho bất biến phụ thuộc vào chỉ số lặp của vòng lặp. Khi đó, tôi thay thế n bằng p điều đó cho tôi dự đoán một bất biến của vòng lặp trên sẽ là:   min |1 1 1I m f i i p p n        . Công việc tiếp theo là chứng minh biến và bất biến tìm được là đúng : Biến : Chứng minh ban đầu t > 0 . Theo logic Hoare tôi phải chứng minh 0I b t   đồng nghĩa với 1 0p n n p     . Tôi sẽ chứng minh như sau : p n Theo giả thiết 0n p  Chuyển vế p 1 1n p   Cộng 2 vế với 1 45 1 0n p   Tính chất của phép so sánh. Chứng minh sau mỗi lần thực hiện thân vòng lặp biến t phải giảm. Để thực hiện, tôi phải chứng minh vấn đề sau    b t N c t N   , đồng nghĩa với việc chứng minh            1 ( 1) 1 : ( 1) 1 : 1 1 p n n p N f p m n p N m f p n p N p p n p N                      Tôi phải làm rõ hai vấn đề sau + Thứ nhất:   1 ( ( 1) 1 )p n n p N f p m n p N            . Được minh chứng bằng những logic sau 1n p N   Giả thiết 1 1n p N    Định nghĩa phép <  1 1n p N    Quy tắc toán học. + Thứ hai :     1 1p n n p N f p m n p N           . Tôi không thể xác minh được hay nói cách khác là sai. Từ điều này dẫn đến kết luận vòng lặp này sẽ không dừng trong trường hợp chỉ số p không được thỏa mãn để tăng. Bất biến: Để chứng minh I đúng tôi cần chứng minh thỏa mãn vấn đề sau    b I c I Điều đó tương đương với việc chứng minh      min |1 1 1p n m f i i p p n f p m                min |1 1 1 1 1f p f i i p p n          :m f p    min |1 1 1 1 1m f i i p p n         b I Luật phép gán, tuần tự. Luật phép gán 46 : 1p p     min |1 1 1m f i i p p n       + Tôi làm rõ vấn đề thứ nhất:    P b c Q      min |1 1 2 1p n m f i i p p n f p m                 min |1 1 1 2 1 1f p f i i p p n           Điều này được minh chứng bằng những logic sau 2 1p  2 p 1 1p n   Vì p n   min |1 1m f i i p    Giả thiết        min min |1 1 ,f p f i i p f p    Bởi vì        min |1 1 1 min |1 1 ,f i i p f i i p f p              min m,f p f p f p  Vì  f p m + Tôi làm rõ vấn đề thứ hai:  P b Q       min |1 1 2 1p n m f i i p p n f p m               min |1 1 2 1m f i i p p n         . Điều này hiển nhiên đúng. Kết luận: Biến và bất biến tìm được là đúng. Tuy nhiên vòng lặp sẽ không dừng trong trường hợp gặp phải f (p) ≥ m. Bài 3. Cho chương trình (tựa mã) như sau: m := 0; p := 1; q := n; while p < q do if f (q) > f (p) then q := q – 1; else p := p + 1; m := f (p); I 47 Hãy xác định biến (t) và bất biến (I) đúng để chứng minh tính đúng đắn của chương trình. Bài giải: Tôi dự đoán biến và bất biến như sau Biến Chú ý vào điều kiện của vòng lặp tôi thấy hai biến chỉ số là p và q đều có thể được thay đổi giá trị. Chỉ số p tăng lên và q giảm dần giá trị. Vòng lặp kết thúc khi p = q. Dạng này tôi dự đoán biến t = q – p. Hiệu q – p = 0, đồng nghĩa với vòng lặp kết thúc khi p = q. Bất biến: Chương trình này dùng để tìm số nhỏ nhất của dãy số. Hậu điều kiện tổng quát của chương trình là “m = min {f(i) | 1 ≤ i ≤ n }”. Sử dụng kỹ thuật giảm dư hằng, tôi dùng một cặp biến chỉ số của vòng lặp là p và q. Với 1 ≤ p≤q ≤ n, Tôi dự đoán một bất biến đó là:    1 { | } { | }min f i i n miI n f i p i q     . Chứng minh biến và bất biến đã dự đoán là đúng Biến Chứng minh đầu tiên biến phải dương, t > 0. Tôi phải chứng minh 0b t  , điều đó đồng nghĩa với việc chứng minh 0p q q p    . Thỏa mãn bằng những logic sau p q Giả thiết 0q p  Chuyển vế Chứng minh sau khi thực hiện thân vòng lặp biến phải giảm giá trị    b t N c t N   . Đối với chương trình này tôi phải chứng minh  p q q p N        : –1 f p f q q q   if then Tôi cần chứng minh hai trường hợp sau   : 1; q p p N p    else 48 Trường hợp f(q) > f(p) cho giá trị true: 1p q q p N q p N        . Điều đó được kiểm chứng bằng những logic sau q p N  Giả thiết 1 1q p N    Trừ cả 2 vế cho 1 1q p N   Định nghĩa phép < Trường hợp cho giá trị false: ( 1)p q q p N q p N        . Điều đó được kiểm chứng bằng những logic sau q p N  Giả thiết 1 1q p N    Trừ cả 2 vế cho 1 1q p N   Định nghĩa phép < ( 1)q p N   Quy luật toán học Bất biến: Áp dụng luật rẽ nhánh tôi sẽ chứng minh như sau Với bất biến dự đoán là    1 { | } { | }min f i i n miI n f i p i q        { | } { | }1 p q min f i i n min f i p i q       if f (q) > f (p) then    1 1{ | } { | }min f i i n min f i p i q      q := q – 1; else    1 { | } +1 { | } min f i i n min f i p i q     p := p + 1;    1 { | } { | }min f i i n miI n f i p i q     + Trường hợp 1: Tôi cần chỉ ra        1 { | } { | }p q min f i i n mi f q f pn f i p i q            1 1{ | } { | }min f i i n min f i p i q       . Điều này được minh chứng bằng những logic sau:    1 { | } { | }min f i i n min f i p i q     Giả thiết     { | } { | } 1min f i p i q min f i p i q      Vì    f q f p 49 + Trường hợp 2: Tôi cần chỉ ra        1 { | } { | }p q min f i i n mi f q f pn f i p i q            1 1 { | } { | }min f i i n min f i p i q       . Điều này được minh chứng bằng những logic sau:    1 { | } { | }min f i i n min f i p i q     Giả thiết    f q f p Giả thiết     { | } { | } 1 min f i p i q min f i p i q      Bởi vì với    f q f p thì min( f(p) , f(p+1) ) = min( f(p+1)). Kết Luận: Bất biến và biến tôi dự đoán là đúng. Bài 4. Cho chương trình (tựa mã) như sau: Với m, i là các biến nguyên, n là một hằng nguyên dương. m := 0; i := 1; while i ≤ n do begin m := m + i*i; i := i + 1 end end Hãy xác định biến (t) và bất biến (I) đúng để chứng minh tính đúng đắn của chương trình. Giải: Tôi dự đoán biến và bất biến như sau Biến Với kinh nghiệm có được tôi nhìn nhận rất nhanh vòng lặp thực hiện với một chỉ số lặp i. Giá trị của chỉ số i tăng dần sau mỗi lần thực hiện thân vòng lặp. Vòng lặp kết thúc khi i vượt quá n. Từ đó tôi dự đoán biến t = n – i +1. Bất biến Từ đoạn chương trình trên, tôi có thể khái quát hậu điều kiện là 2 1 n j m j   . Từ kinh nghiệm làm các bài toán tìm bất biến, đối với dạng bài toán này tôi áp dụng kỹ thuật giảm dư hằng, thay biến n bằng biến chỉ số i nhằm mục đích làm cho bất biến phụ thuộc vào biến chỉ số của vòng lặp. Bên cạnh đó tôi nhận thấy bất biến chặn của vòng lặp là 1 1i n   , khi i = n+1 vòng lặp sẽ dừng lại. Từ 50 những dự đoán trên, tôi chọn được một bất biến vòng lặp là 1 2 0 1 1 i j I i n m j         . Tới đây, tôi cần chứng minh biến và bất biến tìm được là đúng, như sau: Biến Biến chức năng dự đoán của tôi là t = n – i +1. Chứng minh đầu tiên t > 0. Để làm được điều đó tôi thực hiện chứng minh 0b t  đồng nghĩa với 1 0i n t n i      . Giống như bài toán 2, Tôi sẽ chứng minh như sau: i n Theo giả thiết 0n i  Chuyển vế p 1 1n i   Cộng 2 vế với 1 1 0n i   Tính chất của phép so sánh. Chứng minh sau mỗi lần thực hiện thân vòng lặp biến t phải giảm. Để thực hiện, tôi phải chứng minh vấn đề sau    b t N c t N   , đồng nghĩa với việc chứng minh  1i n n i N       1 1n i N    2:m m i    1 1n i N    : 1;i i   1n i N   Khi đó, tôi phải chứng minh vấn đề sau là đúng  1 1 1i n n i N n i N          . Điều đó dễ dàng được kiểm chứng bằng những logic sau: 1n i N   Giả thiết 1 1n i N    Tính chất phép <  1 1n i N    Quy tắc toán học Bất biến b t N  Phép gán, tuần tự Phép gán t N 51 Tôi chứng minh bất biến sau khi thực hiện thân vòng lặp vẫn được bảo toàn. Với 1 2 0 1 1 i j I i n m j         . Tôi cần chứng minh    b I c I tương đương với việc chứng minh thỏa mãn 1 2 0 1 1 i j i n m j i n                1 1 2 2 0 1 1 1 i j i n m i j                 m := m + i*i 1 1 2 0 1 1 1 i j i n m j                i := i + 1 1 2 0 1 1 i j i n m j              Tôi phải cho thấy 1 1 1 2 2 2 0 1 1 1 1 1 1 i i j j i n i n m j i n m i j                      . Thỏa mãn bằng các logic sau: i n Giả thiết 1 1i n   Cộng cả hai vế với 1   1 22 2 0 1 ... 1 i j m j i        Theo giả thiết   1 1 22 2 2 2 2 1 1 2 ... 1 i j m i j i i            Cộng hai vế với 2i . Kết luận: Bất biến và biến tôi dự đoán là đúng. Bài 5. Cho chương trình (tựa mã) sau: Cho m, i là các biến nguyên, n là một hằng nguyên dương. m := 0; i := 1; while i ≤ n do begin if (i mod 2 = 0) then m := m + i ∗ i ∗ i; i := i + 1; b I Phép gán, tuần tự Luật phép gán I 52 end Hãy tìm biến (t) và bất biến (I) để chứng minh tính đúng đắn của chương trình. Giải: Tôi dự đoán biến và bất biến Biến: Giống các bài toán 2, 4 ở trên, áp dụng dạng mẫu trong trường hợp có một biến chỉ số vòng lặp i, tôi có biến t = n – i +1. Bất biến: Bài toán trên là bài toán dùng để tính tổng các số chẵn mũ ba không vượt quá n. Tôi có thể đưa ra một hậu điều kiện tổng quát như sau    /2 3 1 2* n j m j   . Với [n/2] nghĩa là n chia cho 2 lấy phần nguyên. Nhận thấy biến chỉ số của vòng lặp là i chạy trong miền giá trị 1 1i n   tạo nên bất biến chặn. Áp dụng kỹ thuật giảm dư hằng tôi thay n bằng biến chỉ số i. Khi đó tôi được một bất biến như sau:    1 /2 3 0 1 1 2* i j I i n m j            . Chứng minh biến và bất biến tìm được là đúng: Biến Đầu tiên tôi chứng minh t > 0. 0b t  đồng nghĩa với 1 0i n n i     . Điều này được kiểm chứng bằng những logic sau: i n Theo giả thiết 0n i  Chuyển vế 1 0n i   Tính chất của phép > Tiếp theo tôi chứng minh sau khi thực hiện thân vòng lặp t phải giảm giá trị    b t N c t N   .  1i n n i N       2 0i mod if then : ;m m i i i    : 1;i i   1n i N   Áp dụng luật điều kiện đối với   2 0 :i mod m m i i i    if then Tôi thấy không thay đổi giá trị của i. khi đó tôi cần chứng minh 1 ( 1) 1i n n i N n i N          . Điều đó được kiểm chứng bằng các logic sau: 1n i N   Theo giả thiết 53 1 1n i N    Định nghĩa của phép < ( 1) 1n i N    Quy tắc toán học Bất biến    1 /2 3 0 1 1 2* i j i n i n m j                      2 0i mod if then : ;m m i i i    : 1;i i     1 /2 3 0 1 1 2* i j i n m j                  Tôi phải chứng minh hai trường hợp sau + Trường hợp 1:    1 /2 3 0 1 1 2* i j i n i n m j                       1 /2 3 0 1 1 2* ( mod2 0) i j i n i n m j i                         1 1 /2 33 0 1 1 1 2* i j i n m i j                     : ;m m i i i       1 1 /2 3 0 1 1 1 2* i j i n m j                    : 1;i i     1 /2 3 0 1 1 2* i j i n m j                  Tôi cần phải cho thấy b I Luật rẽ nhánh (i mod 2 = 0: true) Luật gán, luật ghép Luật gán {I} 54    1 /2 3 0 1 1 2* ( mod2 0) i j i n i n m j i                         1 1 /2 33 0 1 1 1 2* i j i n m i j                      . Điều đó được minh chứng bằng những logic sau: 1 1i n   Vì i n 1 1i  Vì 1 i    1 /2 3 0 2* i j m j       Theo giả thiết        1 /2 1 1 /2 3 33 3 0 0 2* 2* i i j j m i j i j                 Vì  1 /2 1 /2i i         với mod2 0i  . + Trường hợp 2:    1 /2 3 0 1 1 2* i j i n i n m j                       1 /2 3 0 1 1 2* ( mod2 0) i j i n i n m j i                         1 1 /2 3 0 1 1 1 2* i j i n m j                    : 1;i i     1 /2 3 0 1 1 2* i j i n m j                  Tôi cần phải cho thấy    1 /2 3 0 1 1 2* ( mod2 0) i j i n i n m j i                         1 1 /2 3 0 1 1 1 2* i j i n m j                     . Điều đó được minh chứng bằng những logic sau: b I Luật rẽ nhánh (i mod 2 = 0: false) Luật phép gán {I} 55 1 1i n   Vì i n 1 1i  Vì 1 i    1 /2 3 0 2* i j m j       Theo giả thiết        1 1 /2 1 /2 3 3 0 0 2* 2* i i j j m j j               Vì  1 /2 /2i i        với mod2 0i  Kết luận: Bất biến và biến tôi dự đoán là đúng. Bài 6. Cho chương trình (tựa mã) sau: Cho m, i là các biến nguyên, n là một hằng nguyên dương. m := 0; i := 1; while i ≤ n do begin if (i mod 2 = 1) then m := m + i ∗ i ∗ i; i := i + 1; end Hãy tìm biến (t) và bất biến (I) để chứng minh tính đúng đắn của chương trình. Giải: Tôi dự đoán biến và bất biến: Biến: Giống các bài toán 2, 4, 5 ở trên, áp dụng dạng mẫu trong trường hợp có một biến chỉ số vòng lặp i, tôi có biến t = n – i +1. Bất biến: Bài toán trên là bài toán dùng để tính tổng các số lẻ mũ ba không vượt quá n. Tôi có thể đưa ra một hậu điều kiện tổng quát như sau    1 /2 3 0 2* 1 n j m j       . Với [n/2] nghĩa là n chia cho 2 lấy phần nguyên. Nhận thấy biến chỉ số của vòng lặp 1 1i n   tạo nên bất biến chặn. Áp dụng kỹ thuật giảm dư hằng tôi thay n bằng biến chỉ số i. Khi đó tôi được một bất biến như sau:    2 /2 3 0 1 1 2* 1 i j I i n m j            . Chứng minh biến và bất biến vừa tìm được là đúng: Biến Với biến là t = n – i +1, tôi thực hiện chứng minh giống với bài toán 4. Kết luận biến t tìm được thỏa mãn yêu cầu. 56 Bất biến    2 /2 3 0 1 1 2* 1 i j i n i n m j                       2 1i mod if then : ;m m i i i    : 1;i i     1 /2 3 0 1 1 2* 1 i j i n m j                   Tôi phải chứng minh hai trường hợp sau (các phân tích đã được tối giản, có thể xem chi tiết ở bài toán 5). + Trường hợp 1: Tôi cần phải cho thấy    2 /2 3 0 1 1 2* 1 ( mod 2 1) i j i n i n m j i                          1 2 /2 33 0 1 1 1 2* 1 i j i n m i j                       . Điều đó được minh chứng bằng những logic sau: 1 1i n   Vì i n 1 1i  Vì 1 i    2 /2 3 0 2* 1 i j m j       Theo giả thiết        2 /2 1 2 /2 3 33 3 0 0 2* 1 2* 1 i i j j m i j i j                   Vì    2 /2 1 1 /2i i          với mod 2 1i  . + Trường hợp 2: Tôi cần phải cho thấy 57    2 /2 3 0 1 1 2* 1 ( mod 2 1) i j i n i n m j i                          1 2 /2 3 0 1 1 1 2* 1 i j i n m j                      . Điều đó được minh chứng bằng những logic sau: 1 1i n   Vì i n 1 1i  Vì 1 i        1 2 /2 2 /2 3 3 0 0 2* 1 2* 1 i i j j m j j                 Vì    1 2 /2 2 /2i i          với mod2 0i  Kết luận: Bất biến và biến tôi dự đoán là đúng. Bài 7. Cho chương trình (tựa mã) sau: với x,y,z là các biến nguyên, n là một hằng nguyên dương. x = 0 ; y = 1 ; z = 1 ; 1 ≤ n While z < n do begin y := x + y; x := y – x; z := z + 1; end {y = fib n} Tìm biến ( t ) và bất biến ( I ) để chứng minh tính đúng đắn của lệnh chu trình. Giải: Dự đoán biến và bất biến Biến Từ những bài toán đã làm, tôi dễ dàng đưa ra dự đoán biến chức năng của lệnh chu trình trên là t = n – z. Khi z = n vòng lặp sẽ chấm dứt. Bất biến Tôi thấy đoạn chương trình dùng để tính số fibonacci của một số nguyên n (1 ≤ n). Hậu điều kiện tổng quát là y = fib ( n ). Bằng cách thay thế n bởi biến chỉ số trong điều kiện lặp. Với z chạy trong miền giá trị từ 1 đến n, tôi thấy biến x và y lần lượt sẽ nhận các giá trị fib như sau: y = fib (z) và x = fib (z-1). 58 Từ những phân tích và kỹ thuật áp dụng phương pháp giảm dư hằng, tôi đưa ra dự đoán biết biến của vòng lặp là    1I y fib z x fib z z n       Chứng minh biến và bất biến vừa tìm được là đúng. Biến Chứng minh ban đầu t > 0. Tôi phải chứng minh 0b t  . Khi đó, tôi cần chỉ ra rằng 0z n n z    . Điều này hiển nhiên đúng. Chứng minh    b t N c t N   . Áp dụng luật phép gán và phép ghép, tôi có: z n n z N     1n z N   y := x + y; x := y – x;  1n z N   z := z + 1 n z N  Tôi cần chỉ ra rằng  1z n n z N n z N        . Điều đó được minh chứng bằng những logic sau: n z N  Giả thiết 1 1n z N    Trừ 1 cả hai vế  1n z N   1N N  Bất biến Tôi chứng minh    b I c I . Áp dụng luật phép gán và ghép tôi có:    1y fib z x fib z z n z n           1 1 1 1x y fib z x y x fib z z n            y := x + y;    1 1 1 1y fib z y x fib z z n          x := y – x;    1 1 1 1y fib z x fib z z n         z := z + 1    1y fib z x fib z z n      Khi đó, tôi cần phải chỉ ra rằng 59    1y fib z x fib z z n          1 1x y fib z y fib z z n        Điều đó được minh chứng như sau: 1z n  Vì z n  y fib z Theo giả thiết  1x fib z  Theo giả thiết      1 1y x fib z fib z fib z      Tính chất dãy fibonacci Kết luận: Bất biến và biến tôi dự đoán là đúng. Bài 8. Cho chương trình ( tựa mã ) sau: với r, s, x là các biến nguyên, y là một số nguyên dương. r:=0; s:= -1; x:= 0; While r ≤ y do Begin s:= s + 2; r:= r + s; x := x + 1; End Tìm biết ( t ) và bất biến ( I ) để chứng minh tính đúng đắn của lệnh chu trình. Giải: Dự đoán biến và bất biến Biến Nhận thấy biến chỉ số r tăng tuần tự và là bình phương của x. Vòng lặp sẽ kết thúc khi r vượt quá n. Đối với dạng điều kiện lặp có một biến chỉ số (r), theo kinh nghiệm tôi đưa ra một biến chức năng t = n – r + 1. Ở đầu ra của vòng lặp biến chức năng sẽ có giá trị t ≤ 0. Bất biến Phân tích qua đoạn chương trình tôi nhận thấy nó dùng để trả ra phần nguyên căn bậc hai của một số nguyên dương y ([√y] = x -1). Các biến trong thân vòng lặp có giá trị s = 2x - 1, 2r x . Tôi dự đoán một bất biến vòng lặp từ những dữ liệu vừa phân tích   22 2 1 1I r x s x x y        Chứng minh biến và bất biến vừa tìm được là đúng. Biến 60 Xem lại chứng minh ở bài 2, 4, 5, 6. Bất biến Tôi chứng minh    b I c I . Áp dụng vào thân vòng lặp tôi có   22 2 1 1r x s x x y r y         I b   2 22 1 2 2 1r s x s x x y          s:= s + 2;   2 21 2 1r s x s x x y        r:= r + s;   2 21 2 1r x s x x y       x := x + 1;   22 2 1 1r x s x x y       Có   2 22 1 2 2 1r s x s x x y           2 22 1r x s x x y      . Khi đó tôi cần phải chỉ ra   22 2 1 1r x s x x y r y          2 22 1r x s x x y      . Điều đó được minh chứng bằng những logic sau: 2r x Theo giả thiết 2 1s x  Theo giả thiết r y Theo giả thiết 2x y Vì 2r x . Kết luận : Bất biến và biến tôi dự đoán là đúng. Như vậy, tôi nhận thấy vấn đề tìm biến và bất biến để chứng minh tính đúng đắn của lệnh chu trình thực sự không thể tìm được một phương pháp chung nhất, hay phương pháp đảm bảo tối ưu. Vì cơ bản những bài toán khác nhau đều có hậu điều kiện và các ràng buộc khác nhau, điều đó mang lại sự đa dạng bất quy tắc. Để giải quyết được bài toán này chủ yếu dựa vào các giải pháp được đúc rút ra dựa trên những kinh nghiệm được học hỏi và khám phá trong quá trình tìm tòi. Tất cả các kinh nghiệm đó đã được tôi trình bày trong khi làm các bài toán tìm biến (t) , Bất biến vòng lặp (I), và các bài toán chứng minh tính đúng đắn của chương trình. Luật ghép Luật ghép Luật phép gán I 61 CHƯƠNG 5. KẾT LUẬN 5.1 Kết luận Các kết quả nghiên cứu về đề tài chứng minh tính đúng đắn của chu trình bằng logic Hoare không phải là mới nhưng thực sự nó vẫn còn mang tính thời sự. Việc áp dụng vào thực tế trong việc chứng minh tính đúng của chương trình góp phần quan trọng để đảm bảo một chương trình thỏa mãn yêu cầu lập trình. Trong phần luận văn tôi đã cố gắng dẫn dắt những kiến thức theo một logic hợp lý và trực quan nhất. Những lý thuyết cơ bản và bài toán ví dụ được đưa ra xen kẽ và liên tục (từ chương 2 đến chương 4) với mục đích không chỉ là cung cấp lý thuyết mà còn đem lại cho bản thân cũng như người đọc một vài kinh nghiệm rút ra trong việc tìm biến và bất biến để chứng minh tính đúng đắn của lệnh chu trình. Những kiến thức của phần luận văn có thể được tổng hợp một cách vắn tắt như sau: Đầu tiên là những kiến thức tổng quan về logic vị từ, logic Hoare; Các kỹ thuật chứng minh tính đúng của lệnh chu trình bằng phương pháp logic Hoare kèm vào đó là các ví dụ minh họa chi tiết cho việc chứng minh; Làm rõ hơn về biến và bất biến, đi xâu vào tìm hiểu về bất biến vòng lặp, các ví dụ minh họa được thể hiện trên một vài thuật toán cơ bản nhất; Cuối cùng các kinh nghiệm rút ra từ việc nghiên cứu trong quá trình thực hiện tìm biến, bất biến trên các ví dụ bài toán vòng lặp cụ thể. Trên thực tế có nhiều công cụ tự động trong việc chứng minh tính đúng đắn của chương trình, tuy nhiên hiểu rõ phương pháp chứng minh, hiểu rõ bản chất của vòng lặp luôn làm cho người lập trình ít mắc sai sót trong quá trình viết code. Khi đó, chương trình được viết ra sẽ đảm bảo chạy đúng và ổn định hơn. Nó góp phần giảm thiểu rủi ro và kinh phí sửa chữa, bảo trì. Qua quá trình nghiên cứu về luận văn, bản thân tôi đã lĩnh hội được một lượng kiến thức khá lớn từ đó đã làm rõ những ưu tư, thắc mắc của mình trong quá trình giảng dạy bộ môn tin học tại cấp độ THPT. Đó là những kiến thức liên quan đến tính đúng đắn của chương trình, đến bản chất của vòng lặp, đến tính kết thúcThực sự rất là hữu ích trong việc giảng dạy học sinh lớp 10 (trong các bài liên quan đến thuật toán), học sinh lớp 11 (giảng dạy về ngôn ngữ lập trình, Pascal). 5.2 Hạn chế và kiến nghị Sau khi nghiên cứu, tôi đã cố gắng tổng hợp, phân tích các tài liệu liên quan đến luận văn, tham khảo ý kiến hướng dẫn của TS. Đặng Văn Hưng nhằm mục đích tìm ra một phương pháp giải cơ bản nhất cho bài toán tìm biến và bất biến 62 cho việc sử dụng logic Hoare để chứng minh tính đúng đắn. Tuy nhiên, sẽ chẳng có một phương pháp hay một lời giải nào chung nhất và tốt nhất. Cơ bản phần nhiều nó dựa trên những kinh nghiệm có được trong quá trình tìm kiếm. Chắc chắn rằng với trình độ hạn hẹp của bản thân và trong thời gian nghiên cứu làm luận văn, công việc dạy học cộng thêm đó là việc gia đình con nhỏ làm cho bản thân thực sự chưa hoàn thành được luận văn ở mức độ cao nhất mong muốn. Luận văn được viết ra chắc sẽ còn những mặt hạn chế, sai sót. Vậy, tôi rất mong nhận được sự quan tâm, đồng cảm và đóng góp ý kiến từ phía thầy cô, bạn bè để luận văn được hoàn thiện hơn. 63 TÀI LIỆU THAM KHẢO Tiếng Việt [1] Đỗ Đức Giáo (2011), Toán rời rạc ứng dụng trong tin học, Nhà xuất bản giáo dục Việt Nam. [2] Lê Văn Viễn, Phương pháp kiểm chứng tính đúng đắn của một chương trình Java đa luồng thông qua sử dụng logic Hoare, Báo cáo tốt nghiệp. [3] Zoharn Manna, Người dịch TS. Đặng Văn Hưng, Lô Gích về lập trình, Trung tâm toán máy tính. Tiếng Anh [4] Jonathan Aldrich, 17-654/17-765 Analysis of Software Artifacts. [5] C.A.R. Hoare, An Axiomatic Basis for Computer Programming, The Queen’s University of Belfast, *Northern Ireland. [6] Dang Van Hung, Formal Methods An Introduction, College of Technology. [7] CARLO A. FURIA, ETH Zurich, BERTRAND MEYER, Loop invariants: analysis, classification, and examples, ITMO St. Petersburg, and Eiffel Software, SERGEY VELDER. [8] Ichiro Hasuo, Tutorial on Formal Verification using Hoare Logic, Dept. Computer Science, University of Tokyo. [9] Anders Møller, Program Verification with Hoare Logic, university of Aarhus.

Các file đính kèm theo tài liệu này:

  • pdfluan_van_phat_trien_cac_ky_thuat_tim_bat_bien_invariants_va.pdf
Luận văn liên quan