Ngữ nghĩa tới được là trừu tượng hoá của ngữ nghĩa RTC

Một phần của tài liệu Nghiên cứu kỹ thuật giải thích trừu tượng (Trang 49)

Ngữ nghĩa tới được của hệ dịch chuyển = 〈 , , 〉 là một tập

{ ′|∃ ∈ : 〈 , ′〉 ∈ ∗} các trạng thái mà là tới được từ các trạng thái khởi đầu . Đây là một trừu tượng •( ∗) của ngữ nghĩa bao đóng phản xạ bắc cầu ∗ bởi định nghĩa ảnh phải (Right-image) [ ] = { ′|∃ ∈ : 〈 , ′〉 ∈

} của tập với quan hệ và •( ) = [ ] = { ′|∃ ∈ : 〈 , ′〉 ∈ }. Để cho •( ) = {〈 , ′〉| ∈ ⟹ ′ ∈ }. Chúng ta có kết nối Galois: •( ) ⊆ ⟺ { ′|∃ ∈ : 〈 , ′〉 ∈ } ⊆ (theo định nghĩa •)

⟺ ∀ ′: ∀ ∈ : 〈 , ′〉 ∈ ⟹ ′ ∈ (theo định nghĩa quan hệ bao hàm ⊆)

⟺ ∀〈 , ′〉 ∈ : ∈ ⟹ ′ ∈ (theo định nghĩa phép kéo theo ⟹)

⟺ ⊆ {〈 , ′〉 ∈ ⇒ ′ ∈ } ⟺ ⊆ •( ) (theo định nghĩa ⊆, •) [5] 2.7.8. Biểu diễn ngữ nghĩa tới được dưới dạng điểm cố định

Để thiết lập tính chất chuyển đổi, chúng ta chứng minh rằng

•(ℱ∗( )) = { ′|∃ ∈ : 〈 , ′〉 ∈ (1 ∪ ∘ )} (theo định nghĩa •và ℱ∗)

= { ′|∃ ∈ : ′ = } ∪ { ′|∃ ∈ : ∃ ′′: 〈 , ′′〉 ∈ ∧ 〈 ′′, ′〉 ∈ }

(theo định nghĩa và hàm hợp ∘ )

= ∪ { ′|∃ ′′ ∈ •( ) ∧ 〈 ′′, ′〉 ∈ } (theo định nghĩa •)

= ℱ•( •( )) (theo định nghĩa ℱ•( ) = ∪ [ ] ) Bằng lý thuyết chuyển đổi điểm cố định suy ra rằng

•( ∗) = •( ∅⊆ℱ∗) = ∅⊆ℱ•

Quan sát thấy rằng, nếu Σ là một tập hữu hạn thì chúng ta có một thuật toán lặp tới được tiến (forward reachability iterative algorithm) khi đó

48

∅⊆ℱ• = ⋃ ℱ• (∅) có thể được sử dụng để kiểm tra tất cả các trạng thái tới được thỏa mãn một đặc tả an toàn S: •( ∗) ⊆ ⟺ ∀ : ℱ• (∅) ⊆ .

Hình 2.26: Trừu tượng hóa đến ngữ nghĩa tới được

Trong hình 2.26 mô tả các biểu diễn của ngữ nghĩa thông qua quá trình từ tượng hóa lẫn nhau, bắt đầu từ hệ chuyên dịch, đến ngữ nghĩa vết và cuối cùng là ngữ nghĩa tới được [7].

2.8. Kết luận chương 2

Trong chương này, tôi đã trình bày các khái niệm cơ bản về kỹ thuật giải thích trừu tượng, cơ sở toán học của kỹ thuật giải thích trừu tượng: lý thuyết dàn, lý thuyết điểm cố định, biểu diễn ngữ nghĩa chương trình trên một dàn, kết nối Galois, ….

Các phương pháp biểu diễn ngữ nghĩa chương trình dưới dạng quan hệ chuyển tiếp, hệ chuyển dịch, trừu tượng hóa ngữ nghĩa chương trình, biểu diễn ngữ nghĩa vết dưới dạng điểm cố định, trừu tượng hóa ngữ nghĩa vết bằng bao đóng phản xạ bắc cầu, …, các ngữ nghĩa được trừu tượng hóa lẫn nhau để tối ưu hóa phân tích chương trình tĩnh sẽ được ứng dung trong chương 3.

49

Chương 3 - THỰC NGHIỆM 3.1. Giới thiệu về TVLA

TVLA (3 – Valued Logic Analysis Engine) là một công cụ mã nguồn mở được xây dựng và làm việc trên môi trường Java, được phát triển bởi Lev- Ami Đại học Khoa học Máy tính Tel Aviv (School of Computer Science Tel Aviv University), thành phố Tel Aviv - Israel, nhằm phục vụ mục tiêu nghiên cứu, phát triển lý thuyết giải thích trừu tượng. Là một công cụ mạnh cho việc trừu tượng hóa các đối tượng. Nó cho phép tự động tạo ra sự mô tả trừu tượng từ các ngữ nghĩa, đối tượng cụ thể, cung cấp chế độ kiểm tra thuộc tính liên quan đến heap của chương trình, TVLA có giao diện làm việc là dòng lệnh.

TVLA có các tính năng sau:

 Hỗ trợ ngôn ngữ đặc tả để biểu diễn ngữ nghĩa cụ thể của một chương trình;

 Tự động sinh biểu diễn trừu tượng của ngữ nghĩa cụ thể;

 Có thể điều chỉnh các kết quả trừu tượng và quá trình biến đổi trừu tượng.

Cấu trúc thực hiện lệnh TVLA như sau:

tvla <là tên của chương trình> [tệp dữ liệu vào] [các lựa chọn] Trong đó các lựa chọn gồm có:

- d : Bật chế độ gỡ lỗi.

- action [f][c]pu[c]b: Xác định chế độ ưu tiên khi thực hiện các toán tử. Mặc định fpucb.

f - Focus, c - Coerce, p - Precondition. u - Update, b - Blur.

- join [algorithm]: Định kiểu liên kết các phương thức áp dụng. rel - Kết hợp các liên hệ.

part - Kết hợp một phần.

50 - ms <number>: Giới hạn cấu trúc. - mm <number>: Giới hạn thông báo.

- save {back|ext|all}: Xác định thời gian lưu cấu trúc bộ nhớ. back - Mỗi khi quay lại đỉnh đã xét (mặc định).

ext - Mỗi khi bắt đầu xử lý đối tượng khác. all - Tại mỗi vị trí của chương trình.

- noautomatic: Không tự động phát sinh các ràng buộc. - props <file name>: Có thể sử dụng đặc tả thuộc tính tệp. - log <file name>: Ghi các bước thực hiện ra tệp.

- tvs <file name>: Tạo tệp kết quả đầu ra định dạng TVS. - xml <file name>: Tạo tệp kết quả định dạng XML của CFG

- tr:tvs <file name>: Tạo tệp đầu ra quan hệ chuyển tiếp định dạng TVS - dot <file name>: Tạo tệp kết quả định dạng DOT.

- tr:dot <file name>: Tạo tệp đầu ra quan hệ chuyển tiếp định dạng DOT. - D<macro name>[(value)]: Thiết lập một Macro tiền xử lý bằng C. - nowarnings: Bỏ qua tất cả các cảnh báo.

- path <directory path>: Đường dẫn để thực hiện chương trình. - post: Đánh giá hành động.

3.2. Phân tích trong TVLA

Kỹ thuật giải thích trừu tượng trong phân tích tĩnh cho phép tóm tắt hành vi (ngữ nghĩa cụ thể) của lệnh trong chương trình trên tập vô hạn các trạng thái có thể của bộ nhớ.

Kết quả sau tóm tắt được gọi là ngữ nghĩa trừu tượng của lệnh đó. Ngữ nghĩa cụ thể của một lệnh trong chương trình thường được biểu diễn thông qua các phương pháp hình thức và được sử dụng khá tự nhiên.

Tuy nhiên, trừu tượng hóa ngữ nghĩa cụ thể để tạo ra ngữ nghĩa trừu tượng đảm bảo tính mạnh, chính xác và có khả năng lập luận được lại là một vấn đề khó khăn. Điều này đặc biệt đúng với một số vấn đề trong thực tế như:

51

phân tích hình dạng (Shape Analysis), phân tích con trỏ, trong đó ngữ nghĩa cụ thể liên quan trực tiếp tới cấu trúc dữ liệu và bộ nhớ.

Trong các kỹ thuật phân tích hình dạng thì phân tích hình dạng dựa trên 3-valued logic (Parametric Shape analysis via 3-valued logic) cho đến nay vẫn là phương pháp chính để phân tích heap của chương trình.

Kỹ thuật này được giới thiệu bởi Sagiv [1]. Sau đó Lev-Ami cài đặt các ý tưởng trong phương pháp này và tạo ra công cụ TVLA [13]. TVLA bắt đầu với ngữ nghĩa cụ thể (ngữ nghĩa thực thi - Operationl semantics) của một chương trình. Ngữ nghĩa thực thi được đặc tả bằng logic vị từ cấp một với bao đóng bắc cầu.

Một đầu vào nữa của TVLA là biểu diễn trừu tượng của tất cả các trạng thái bộ nhớ ở điểm vào của chương trình cần phân tích. TVLA sẽ tự động sinh ra ngữ nghĩa trừu tượng, và với mỗi điểm chương trình (program point) sinh ra một giải thích trừu tượng của các trạng thái bộ nhớ ở điểm đó.

TVLA được cài đặt bằng Java và đã sử dụng thành công trong việc phân tích hình dạng của các chương trình thao tác với các danh sách liên kết (danh sách liên kết đơn, danh sách liên kết kép, ..), để chứng minh tính an toàn của hệ thống Mobile Ambients, và xác minh tính đúng đắn cục bộ của một số chương trình sắp xếp (thao tác trên danh sách liên kết).

3.2.1. Cấu trúc 3-valued Logic

Cấu trúc 3-valued logic của Kleene được mở rộng từ 2-valued logic thông thường bởi việc đưa thêm giá trị đặc biệt ½ (giá trị chưa xác định). Các toán tử mệnh đề được Kleene thể hiện trong Hình 3.1.

Giá trị 0 và 1 được gọi là các giá trị xác định, giá trị 1/2 được gọi là giá trị chưa xác định và định nghĩa một quan hệ thứ tự từng phần ⊑ về giá trị

chân lý để phản ánh thông tin: l1 l2 thể hiện rằng l1 có nhiều thông tin xác

52

Hình 3.1: Các toán tử 3-valued logic của Kleene

Định nghĩa 3.1: Cho l1, l2 ∈ {0, 1/2, 1}, ta định nghĩa thứ tự thông

tin trên tập giá trị chân lý như sau: l1 l2 nếu l1 = l2 hoặc l2 = 1/2. Kí

hiệu ⊔ (join) biểu diễn cận trên nhỏ nhất theo quan hệ ⊑, tức là l1 l2 = l1 nếu l1 = l2 và l2=1/2 nếu ngược lại. Ngữ nghĩa của Kleene về 3-valued logic

là đơn điệu theo quan hệ thứ tự trên [13].

3.2.2. Biểu diễn trạng thái bộ nhớ Heap qua cấu trúc Logic

Một cấu trúc 2-valued logic S là một bộ ( , ) trong đó là tập các phần tử (bao gồm các biến và hằng), các phần tử ở đây chính là các nút trên đồ thị Heap (tập các khối bộ nhớ được cấp phát), là tập các vị từ trên

(biểu diễn quan hệ tham chiếu trong Heap). Một vị từ p trên S được kí hiệu là . Với mỗi vị từ p có số chiều k, là hàm: : ( ) ⟶ {0, 1}.

Một heap cụ thể của chương trình được mô tả bằng cấu trúc 2-valued logic: là tập các nút trên đồ thị heap, tức là tập các khối bộ nhớ được cấp phát. Các vị từ biểu diễn quan hệ tham chiếu trong heap. [13]

Vị từ đơn nguyên có thể biểu diễn quan hệ tham chiếu giữa một biến

chương trình với một nút của heap: Nếu biến x tham chiếu tới nút n1, chúng ta tạo một vị từ đơn nguyên x mà x(n1) = 1. Vị từ nhị nguyên được dùng để

biểu diễn tham chiếu giữa các nút (định nghĩa các cạnh giữa các nút trong đồ thị heap). Do đó thông tin về heap được thể hiện thông qua việc đánh giá các vị từ liên quan.

TVLA đưa ra giả định rằng tập tất cả các vị từ là cố định, tuy nhiên tập các phần tử đại diện cho các nút có thể thay đổi trong suốt quá trình phân tích. Hiện tại TVLA chỉ hỗ trợ các vị từ có chiều nhỏ hơn hoặc bằng 2.

53

Các cấu trúc 2-valued logic như trên có thể được thể hiện thông qua

một đồ thị có hướng. Tồn tại một cạnh gán nhãn p hướng từ u1 tới u2 khi

( 1, 2) = 1, p cũng được vẽ trong nút u khi ( ) = 1.

Ví dụ: Hình 3.2 minh họa việc sử dụng một cấu trúc 2-valued logic để biểu diễn một heap gồm 3 nút. Thông tin về heap này được mã hóa bằng tệp TVS trong TVLA như sau:

// Các nút %n = {n1, n2, n3} //Các vị từ %p = { x = {n1} f = {n1 -> n2, n2 -> n3} }

Chúng ta thấy rằng vị từ đơn nguyên x thỏa mãn đối với 1, tức là

( 1) = 1, và n1 có trỏ tới 2 biểu diễn bởi vị từ nhị nguyên , tức là

( 1, 2) = 1. Tương tự ( 2, 3) = 1.

Hình 3.2: Biểu diễn heap cụ thể 3.2.3. Trừu tượng heap

Thay vì sử dụng cấu trúc 2-valued logic, cấu trúc 3-valued logic của Kleene được sử dụng để mô tả heap trừu tượng. Tương tự như cấu trúc 2- valued logic, 3-valued logic chỉ khác ở hàm vị từ: : ( ) ⟶ {0,1,1/2}. Cấu trúc 3-valued logic cũng được biểu diễn bằng các đồ thị có hướng như cấu trúc 2-valued logic nhưng cạnh ứng với giá trị 1/2 được vẽ bằng nét đứt.

TVLA sử dụng một thiết kế đặc biệt cho các vị từ đơn nguyên để duy trì thông tin nút tóm tắt. Một nút tóm tắt như có ( ) = 1/2, chỉ ra rằng có thể đại diện cho nhiều hơn một nút nhúng trong cấu trúc 2-

54

valued logic. Ngược lại, nếu ( ) 0 thì được biết đến là đại diện cho một nút duy nhất. Chỉ có các nút với ( ) = 1/2 có thể có nhiều hơn một nút ánh xạ tới chúng bằng các hàm nhúng [13].

Phép nhúng:

Cho và ’ là 2 cấu trúc, và hàm : → ’ là một toàn ánh, ta nói rằng phép nhúng trong ’ (ký hiệu là ⊑ ’) nếu với mỗi vị từ (bao gồm cả nút đại diện sm): ∀ , … , ∈ , ( , … , ) ⊑

’( ( ), … , ( )) và ∀ ’ ∈ ’: (|{ | ( ) = ’}| > 1) ⊑ ’( ’) Ta nói rằng được nhúng trong ’ nếu tồn tại một hàm được định nghĩa như trên. Một dạng đặc biệt của phép nhúng là phép nhúng hoàn toàn (tight embedding), trong đó lượng thông tin bị thất thoát là nhỏ nhất khi nhiều phần tử của được ánh xạ tới cùng một phần tử trong ’

Nhúng hoàn toàn:

Cấu trúc được nhúng hoàn toàn trong ’ khi tồn tại 1 hàm toàn ánh mờ (surjective function blur) : → ’ thỏa mãn điều kiện: với ∀ ( ≠ )

’( ’ , . . . , ’ ) = ⨆ ( ) ’ , ( , . . . , )

và ’ ∈ ’

’( ’) = (|{ | ( ) = ’}| > 1) ⊔ ⨆ ( ) ( )

Vì hàm blur là toàn ánh nên từ 2 công thức trên ta xác định duy nhất

′ = ( )

Ví dụ: Hình 3.3 thể hiện cùng cấu trúc 2-valued logic trong ví dụ hình 3.2, nhưng sau khi đã được trừu tượng hóa (với là vị từ trừu tượng). Do

( 2) = ( 3) = 0 trong cấu trúc trước nên 2 và 3 được tóm tắt vào cùng một nút trong cấu trúc 3-valued logic.

%n = {n1, n2} %p = { x = {n1}

55

f = {n1 -> n2: 1/2, n2 -> n2: 1/2} sm = {n2: 1/2} // n2 là nút tóm tắt }

Hình 3.3: Trừu tượng hóa heap

Đặc tả heap trừu tượng đầu vào được biểu diễn dưới dạng cấu trúc 3 – valued logic và các thực thi được biểu diễn bằng công thức logic vị từ cấp một. Hệ phương trình ràng buộc được tạo ra từ các đặc tả này bằng thuật toán sinh ràng buộc Coerce [13]. Thuật toán lặp Focus[13] sẽ giải các ràng buộc và tìm điểm cố định nhỏ nhất của hệ phương trình. Nghiệm này chính là biểu diễn trừu tượng của các trạng thái heap có thể có trong quá trình thực thi.

Để xác định hệ phương trình các ràng buộc bằng thuật toán Coerce và giải hệ phương trình ràng buộc Focus sẽ được trình bày trong phần 3.3.

3.2.4. Biểu diễn ngữ nghĩa và chương trình

Để biểu diễn ngữ nghĩa cụ thể của các lệnh trong chương trình TVLA sử dụng các actions. Các actions có thể có tham số và sử dụng logic vị từ để mô tả quá trình chuyển từ một trạng thái tới một trạng thái khác khi lệnh được thực thi. Trong thực tế, tác động trong quá trình chuyển trạng thái được hoàn thành bằng việc sử dụng một tập các công thức vị từ cập nhật (Predicate- update formulae). Các vị từ, các công thức logic và các vị từ cập nhật, được cập nhật lại sau khi chuyển qua trạng thái mới.

Để biểu diễn ngữ nghĩa cụ thể của chương trình, TVLA sử dụng thêm đồ thị luồng điều khiển (Control Flow Graph - CFG), và các cạnh của CFG

được gắn thể hiện của các actions.

Ví dụ: Cho heap trừu tượng trong Hình 3.3 là trạng thái vào và giả sử

56

lập trình điều này có thể được biểu diễn dưới dạng x.f = null. Để biểu diễn quá trình này chúng ta đưa ra một action là setFieldNull(c, n), có thể được sử

dụng để thiết đặt một trường của một nút được trỏ tới bởi một biến trong

chương trình tới giá trị null. Sau đó chúng ta thể hiện action này với x (tương ứng nút n1) và trường f dưới dạng tham số. Cuối cùng là gắn thể hiện của action này với x và f lên cạnh của CFG. Chi tiết được cài đặt theo định dạng

TVP trong TVLA như sau: // Vị từ %p x(v_1) unique %p f(v_1,v_2) function %% // Các actions %action setFieldNull(c,n) { { n(v_1,v_2) = n(v_1,v_2) & !c(v_1) } } %% // CFG

start setNextNull(x,f) end

TVLA sẽ tự động sinh ngữ nghĩa trừu tượng từ ngữ nghĩa cụ thể của chương trình (biểu diễn qua các actions bằng logic vị từ) để thực thi. Kết quả tạo ra heap trừu tượng đầu ra được thể hiện trong Hình 3.4

Hình 3.4: Kết quả heap trừu tượng đầu ra

Tệp TVS đặc tả heap trừu tượng trên được TVLA xuất ra có nội dung như sau: %n = {n1, n2} %p = { x = {n1} f = {n2 -> n2: 1/2} sm = {n2: 1/2} }

57 3.2.5. Ví dụ về phân tích chương trình

Xét đoạn mã chương trình cần phân tích như sau:

/* list.h */

typedef struct node{ struct node *n; int data; } *L; /* reverse.c */ #include ‘‘list.h’’ L reverse(L x){ L y, t; y = NULL; while (x != NULL){ t = y; y = x; x = x->n; y->n = t; t = NULL; } return y; } (a) (b)

(a) là khai báo một kiểu dữ liệu danh sách liên kết trong ngôn ngữ C. (b) là một hàm của C đảo ngược danh sách x thành danh sách y

Trong ví dụ này, một cấu trúc 2 – valued logic đại diện cho một trạng thái bộ nhớ, với ý nghĩa của các vị từ chính và vị từ thiết lập được đưa ra trong Bảng 3.1 dưới đây:

Vị từ Ý nghĩa Định nghĩa công thức x(v) Con trỏ x trỏ đến vị trí của vùng nhớ v

n(v1,v2) n là số con trỏ để đi từ v1 đến v2

r[n,x](v) Có thể truy cập đến vùng nhớ v của con

trỏ x, thông qua n con trỏ. ∃ : ( ( ) ∧ ∗( , ))

c[n](v) Vùng nhớ v xuất hiện trên chu trình có

Một phần của tài liệu Nghiên cứu kỹ thuật giải thích trừu tượng (Trang 49)

Tải bản đầy đủ (PDF)

(90 trang)