2.3.2.1 Ngữ pháp
Ngôn ngữ lập trìnhmục tiêu được sử dụng trong hệ thống của là loại ngôn ngữhoàn toàn hướng đối tượng có thể được xem như là thể hiện chocác ngôn ngữ lập trình phổ biến như C/C++, Java hay C#... Ngữ pháp của nó được định nghĩanhưsau:
Hình2 - Ngôn ngữ chương trình
Một chương trình sẽ bao gồm một danh sách kiểu dữ liệu được khai báo
và danh sách các thủ tục .Ký hiệu * được sử dụng thể hiện danh sách
nhiều item, ví dụ khai báo ký hiệu cho một danh sách các biến . Bảng
dưới đây mô tả ý nghĩa của các ký hiệu cơ bản trong ngôn ngữ chương trình sử dụng:
# Ký hiệu Ý nghĩa
1 Ký hiệu cho tên của kiểu dữ liệu user-defined.
2 Ký hiệu cho khai báo tên biến của chương trình.
3 Ký hiệu khai báo tên của thủ tục chương trình
4 Ký hiệu cho khai báo hằng số
5 Ký hiệu cho tên trường dữ liệu
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang38
7 Ký hiệu khai báo vị từ Shape (Sẽ được trình bày ở
chương tiếp theo)
8 Ký hiệu cho thủ tục
9 Ký hiệu cho tiền/hậu điều kiện của thủ tục
Bảng3 - Ý nghĩa ký hiệu sử dụng trong ngôn ngữ chương trình
Để đơn giản trong cách trình bày nội dung mà không làm mất đi những thể hiện đặc trưng của ngôn ngữ chương trình sử dụng, trong luận văn thể hiện chương trình và những công thức đặc tả chương trình có dạng well-typed (sẽ được trình bày
ở phần tiếp theo), và quy định khi truy cập trường dữ liệu ở mức một (thông
thường có thể viết ).
Trong luận văn sử dụng khai báo dữ liệu node để thể hiện cho hầu hết các ví dụ:
Mỗi một thủ tục được gắn với một đặc tả tiền/hậu điều kiện , cú
pháp của nó sẽ được đề cập trong các phần tiếp theo của luận văn, ý nghĩa của việc sử dụng cặp mô tả tiền/hậu điều kiện cho thủ tục là: Nếu một thủ tục được gọi trong trạng thái hiện tại của chương trình thỏa mãn tiền điều kiện của thủ tục, thì thủ tục sẽ không truy xuất tới vùng bộ nhớ lỗi (vùng nhớ null hoặc con trỏ treo); hay nói cách khác, nếu thủ tục dừng thì nó sẽ dừng trong trạng thái chương trình thỏa mãn hậu điều kiện của thủ tục. Vì thế nếu trạng thái chương trình không thỏa mãn tiền điều kiện thì sẽ dẫn đến phát sinh lỗi.Để đơn giản hóa vấn đề, quy định tên biến trong một thủ tục không được phép trùng lặp.
Trong mỗi thủ tục, những tham số được truyền bởi tham trị sẽ được ký hiệu
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang39
các ngôn ngữ lập trình hiện nay, ví dụ sau minh họa cho việc truyền tham trị mà
thực hiện việc đổi chỗ các tham số mỗi khi thủ tục đổi chỗ được gọi:
Sau đây là mô tả cho thuật toán sắp xếp chèn được sử dụng để minh họa cho các phần lý thuyết được trình bày trong luận văn:
Thủ tục insert sẽ thực hiện việc sắp xếp danh sách x và node vn vào đúng vị trí trong danh sách x. Thủ tục insertion_sort thực hiện lời gọi đệ quytới phần đuôi của danh sách thông qua y.next, trước khi thực hiện việc chèn node đầu tiên của danh sách(y) thì danh sách đã được sắp xếp. Phần đặc tả cho phương thức ký hiệu
làmspecsẽ được mô tả chi tiết trong mục kế tiếp.
2.3.3 Ngôn ngữ đặc tả
Như đã trình bày ở phần trước, một chương trình P được khai báo bao gồm
danh sách kiểu dữ liệu tdecl và danh sách các thủ tục meth, những khai báo này có thể là những vị từ Shape spred hoặc những kiểu đối tượng objt.Mỗi thủ tục được thể
hiện dưới dạng:
Từ đó ta có một tập các cặp tiền/hậu điều kiện, mỗi cặp này được đặc tả dưới dạng nhiều vị từ Shape khác nhau từ đó cho ta thấy được cái nhìn tổng quan hành vi của mỗi thủ tục. Ý nghĩa của một cặp tiền/hậu điều kiện là mỗi khi thủ tục được gọi
trong trạng thái chương trình hiện tại phải thỏa mãn tiền điều kiện , và nếu thủ
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang40
hậu điều kiện , chúng ta sử dụng cách đặc tả tương tự cho thể hiện vòng lặp và
các phương thức khởi tạo khác.
Sử dụng một chú thích cơ bản để thể hiện giá trị hiện tại của những biến cục bộ và thường hay xuất hiện trong hậu điều kiện của các vòng lặp.
Xem xét ví dụsau:
Ở đây x và thể hiện giá trị cũ và giá trị mới của biến x khi bắt đầu và kết thúc một vòng lặp.
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang41
Hình 3 - Ngôn ngữ đặc tả
Việc suy diễn được thực hiện trên vị từ Shape, ngôn ngữ đặc tả chủ yếu thể hiện dưới dạng vị từ Shape với những công thức tách . Mỗi công thức tách bao
gồm ràng buộc Heap (phần Heap-Part) và một phần độc lập với Heap (phần
Pure-Part), phần Pure-Part không chứa bất kỳ Heap Node nào và chỉ thể hiện trong
phạm viso sánh bằng/khác của con trỏ , hay giải thuật Presburger , ràng buộc
Bag .Chú thích thể hiện cho tập các công thức và ràng buộc thể hiện
cho những thuộc tính được chọn. 2.3.3.1 Vị từ User-defined
Để thực hiện việc kiểm định những thuộc tính của một liên kết cấu trúc dữ liệu trong chương trình chúng ta phải đặc tả được những thuộc tính của nó, một vị từ Shape được định nghĩa bao hàm tính đúng đắn cho những thuộc tính của một cấu
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang42
trúc dữ liệu, trong luận văn thì việc đề cập tới vị từ Shape là tương đương với vị từ Heap và thương được gọi ngắn gọn là vị từ.
Một số hệ thống suy diễn Logic được thiết kế làm việc với một tập các vị từ cố định, tuy nhiên do cách thức đặc tả được trình bày có thể định nghĩa cho tất cả các loại cấu trúc dữ liệu nên luận văn cho phép người dùng có thể định nghĩa những kiểu cấu trúc dữ liệu, gọi là User-defined. Những vị từ User-defined cho phép xử lý linh hoạt hơn trong các hệ thống suy diễn do thể hiện được nhiều khía cạnh của các cấu trúc dữ liệu liên kết.
Chúng ta xem xét ví dụ về vị từ cho một danh sách liên kết hở (kết thúc bởi con trỏ Null) như sau:
Trong mô tả về Separation Logic, thể hiện được hiểu
là một Heap đơn được truy cập bởi con trỏ p, trong đó bản ghi dữ liệu gồm có trường val và next.Separation Logic cũng thể hiện công thức vị từ dạng phức tạp hơn khi mô tả đoạn danh sách từ p tới q (lseg(p,q)). Trong
cách thức định nghĩa của luận văn, có một điểm khác trong dạng thức , mà
ở đó khi c là tên của một kiểu dữ liệu thì công thức thể hiện cho một Heap đơn được
trỏ bởi p và là những trường dữ liệu được khai báo. Khi c là tên của một vị từ,thì
công thức thể hiện cho công thức vị từ .Mỗi vị từ có một tham số
đặc biệt là root, đây là tham số đầu tiên của vị từ là một con trỏ đặc biệt cho phépduyệt danh sách cấu trúc dữ liệu và được sử dụng mô tả cho thuộc tính well- founded sẽ được được trình bày trong mục kế tiếp.
Quay trở lại ví dụ vị từ , tham số n thể hiện độ dài của danh
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang43
danh sách bao gồm một con trỏ đầu tiên được trỏ bởi root và
phần cấu trúc dữ liệu còn lại được thể hiện bởi , toán tử kết nối *
đảm bảo rằng phần node đầu tiên và phần còn lại của danh sách nằm trong miền
Heap tách biệt (disjoint Heap).Định nghĩa bất biến thể hiện số lượng node có
trong vị từ, ngoài ra trong cú pháp định nghĩa vị từ còn sử dụng các biến lượng từ i, m, q. Trong công thức vị từ, thì phần Heap độc lập nắm giữ những thực thể (instance) của vị từ và chúng thuộc loại đặc tả well-typed sẽ được đề cập tới ở phần kế tiếp.Các giá trị m, n, i có kiểu dữ liệu nguyên (int), trong khi đó root thuộc kiểu con trỏ. Ngôn ngữ mà luận văn đề cập tới thể hiện những yếu tố cơ bản của đặc tả và bỏ qua đặc tính đa hình trong thể hiện đối tượng.
Trong toàn bộ luận văn ký hiệu gạch dưới thể hiện cho các biến vô danh, những phần không phải là tham số như q luôn luôn được lượng hóa.Trong cách đặc tả vị từ Shape hoặc Node dữ liệu thì tham số root (phần công thức bên trái) có thể được lược bỏ nhằm có thể viết công thức vị từ Shape một cách ngắn gọn hơn, xem xét ví dụ sau đặc tả một sanh sách nối đôi có độ dài n:
Vị từ dll có một tham số p thể hiện cho trường prev của Node đầu tiên trong danh sách nối đôi, việc duyệt danh sách xuất phát từ con trỏ root và duyệt qua các Node tiếp theo bởi trường next. Trong cách đặc tả được đề cập, một vị từ Shape không chỉ mô tả đơn thuần Shape của cấu trúc dữ liệu, mà còn thể hiện các thuộc tính Size và Bag (Khái niệm được nhắc tới ở phần sau), đặc tính này cho phép áp dụng việc đặc tả các cấu trúc dữ liệu có biến động phức tạp.Minh họa cho điều này, xem xét ví dụ định nghĩa một danh sách sắp xếp không rỗng như sau, trong đó vị từ bao gồm độ dài danh sách, giá trị lớn nhất và nhỏ nhất của danh sách:
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang44
Thuộc tính đảm bảo rằng thuộc tính sắp xếp luôn đúng thứ tự giữa
hai phần Heap Node, chúng ta có thể đặc tả (sau đó là kiểm định) giải thuật sắp xếp chèn được đề cập ở phần trước như sau:
Một ký hiệu đặc biệt res được sử dụng trong phần hậu điều kiện thể hiện kết quả trả về của thủ tục, trong ví dụ trên thì thủ tục sắp xếp có kết quả mong đợi là một danh sách đã được sắp xếp và có độ dài không thay đổi là n.
Trong chương này, luận văn đặc biệt nhấn mạnh vào tính tách biệt của suy diễn Separation Logic, ví dụ ta có một khai báo tiền điều kiện của phương thức như sau:
Khai báo thể hiện rằng x.next = y và y:next = x, tuy nhiên ở đây và nó thể
hiện cho hai phần Heap hoàn toàn độc lập. Trong suy diễn cục bộ thì phần Heap được mô tả trong tiền điều kiện chỉ có thể bị thay đổi bởi phần thân của thủ tục mà nó đặc tả.
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang45
2.3.3.2 Chú thích Well-formedness
Nhưđã trình bày, một công thức táchcó thể được sử dụng trong các khai báo tiền điều kiện/hậu điều kiện và những định nghĩa vị từ Shape. Để có thể thao tác chúng một cách chính xác mà không thao tác trên các Heap Node dư thừa, ngôn ngữ đặc tảyêu cầu mỗi ràng buộc tách thuộc dạng well-formed, thông qua các định nghĩa như dưới đây.
Định nghĩa Accessible: Một biến được coi là accessible nếu nó là một tham số hoặc là biến đặc biệt root hay res.
Định nghĩa Reachable: Có ràng buộc và ràng buộc con trỏ , thì tập các Heap Node trong được gọi là reachable từ tập các con trỏ S được tính toán như sau:
Biểu thứcIsPtr(v)kiểm tra xem v có là thuộc kiểu con trỏ hay không.
Định nghĩa Well-Formed: Một công thức được gọi là Well-Formed nếu thỏa mãn,
-Nó thỏa mãn là một công thức tách thông thường ,
trong đó là công thức Heap-part và phần là công thức Pure-part.
-Mọi Heap Node đều thỏa mãn reachable từ tập các biến accessible S.
Đặc tả cũng cần đảm bảo rằng, con trỏ root chỉ xuất hiện trong phần thân của vị từ, và con trỏ res chỉ xuất hiện trong hậu điều kiện. Định nghĩa well-formed đảm
bảo cho thủ tục kiểm tra suy diễn là chính xác, khi thực hiện việc việc match Node
của phần kết luận (consequent) với các Node trong phần tiền đề (antecedent) trong một quan hệ suy diễn (entailment) sẽ được trình bày trong phần sau của luận văn.
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang46
Những quan hệ Shape khai báo đệ quy có thể ảnh hưởng tới tính dừng trong suy diễn unfold/fold. Để tránh ảnh hưởng này, framework trong hệ thống đề cập trong luận văn còn sử dụng khái niệm về những vị từ Well-Founded.
Định nghĩa vị từ Well-Founded: Một vị từ được gọi là well-founded nếu nó thỏa mãn các điều kiện sau:
-Phần thân của nó là công thức thỏa mãn well-formed
- Tất cả các Heap Node đều phải xuất hiện trong phần thân (body)
của đặc tả, trong đó c là tên của kiểu dữ liệu và p=root.
Một ví dụ về vị từ well-founded đặc tả cây nhị phân AVL gần cân bằng như sau:
Xem xét 3 ví dụ sau không thỏa mãn đặc tả well-founded:
Trong ví dụ vị từ foo thì con trỏ root không thỏa mãn duyệt tới toàn bộ các Heap Node; Trong ví dụ goo thì con trỏ được trỏ bởi q không thỏa mãn reachable từ con trỏ root; Trong ví dụ too là sự mở rộng dữ liệu Node không bao hàm bởi biến root. Ví dụ đầu tiên có thể dẫn tới việc unfolding vô hạn, ví dụ thứ hai minh họa cho một Heap Node unreachable trong thủ tục suy diễn. Trong khi đó ví dụ cuối cùng ảnh hưởng tới tính dừng của thủ tục suy diễn chứng minh, thay vào đó ta có thể viết lại:
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang47
Trong đó tmp là một vị từ được thêm vào nhằm thỏa mãn điều kiện well- founded.
Ngoài ra trong ngôn ngữ đặc tả đề cập tới trong luận văn còn sử dụng những thuộc tính Bag trong việc đặc tả các vị từ và thủ tục, sự mở rộng này sẽ được đề cập trong mục tiếp theo trình bày dưới đây.
2.3.3.3 Khái niệm Bag của giá trị/địa chỉ
Trong ví dụ về sắp xếp chèn của phần trước của luận văn hoàn toàn không đề cập tới việc tái sử dụng các ô nhớ, cũng như đảm bảo trật tự sắp xếp của các Node trong danh sách, nguyên nhân bởi các vị từ Shape chỉ thể hiện những con trỏ và số lượng con trỏ nhưng không thể thể hiện được tập những Node reachable trong vị từ Heap.Để giải quyết vấn đề này, kỹ thuật đặc tả được mở rộng khái niệm Bag của những giá trị. Trong luận văn, khái niệm Bag cho phép có thể trùng lặp, và sử dụng
các toán tử như sau: kết hợp , giao , phép gộp , và tập hợp .Khi đó đặc tả
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang48
Với cách đặc tả như trên thi một Bag có thể thể hiện tất cả các Node dữ liệu của cấu trúc dữ liệu (hay vị từ Heap), với sự mở rộng này chúng ta có thể viết đặc tả cho thủ tục chi tiết như sau:
Nhấn mạnh thêm rằng, kỹ thuật đặc tả thông qua Bag thể hiện những Node reachable trong vị từ Shape, thay thế cho việc thể hiện địa chỉ của Heap bằng tập giá trị Bag, minh họa cho việc đặc tả công thức vị từ danh sách liên kết như sau:
Nắm bắt được một tập Bag giá trị, cho phép chúng ta suy diễn trên tập hợp các giá trị của cấu trúc dữ liệu, và cho phép các thuộc tính liên qua có thể được đặc tả vàkiểm địnhhoàn toàn tự động. Xem xét hai ví dụ sau để thấy rõ hơn:
Học viên thực hiện: Nguyễn Đức Cường – Lớp 11BCNTT Trang49
Ví dụ đầu tiên trả về danh sách dữ liệu kiểu pair mà đã thực hiện việc tách danh sách từ một danh sách đơn với chốt là p, đặc tả tiền điều kiện/hậu điều kiện này hoàn toàn có thể được sử dụng trong chứng minh tính đúng đắn của giải thuật sắp xếp nhanhQuicksort. Trong ví dụ thứ hai sử dụng các lượng từ tồn tại và với