Hình 4.1: Kiến trúc hệ thống

Một phần của tài liệu PHƯƠNG PHÁP SINH DỮ LIỆU KIỂM THỬ PHẦN MỀM DỰA TRÊN KỸ THUẬT KIỂM CHỨNG MÔ HÌNH (Trang 42 - 46)

4.3 Chuyển đổi dữ liệu

Thực thi tự động trong JPF sử dụng đầu vào là java byte code, từ Java byte code, việc kết hợp giữa thực thi tự động với JPF core sẽ sinh ra các đối tượng PC. Các PC này sẽ chứa ràng buộc. Một ràng buộc là một lớp bao gồm biểu thức phía trái, biểu thức phía phải, phép so sánh và chính nó:

public abstract class Constraint { private final Expression left; private final Comparator comp; private final Expression right; Constraint and; Các ràng buộc định dạng JPF Định dạng SMT - Lib Z3 Wrapper JAVAPATHFIDER Thực thi Tượng trưng

}

Ví dụ: x + 1 > y +z

Khi đó biểu thức bên trái là x + 1, bên phải là y + z và phép so sánh là phép lớn hơn “ > “.

Một biểu thức cũng sẽ được định nghĩa bao gồm biểu thức bên trái, phép toán và biểu thức bên phải. Bên dưới là lớp định nghĩa biểu thức cho số thực:

class BinaryRealExpression extends RealExpression {

RealExpression left; Operator op;

RealExpression right;

BinaryRealExpression (RealExpression l, Operator o, RealExpression r) {

left = l; op = o; right = r; }

public double solution() {

double l = left.solution(); double r = right.solution(); switch(op){

case PLUS: return l + r; case MINUS: return l - r; case MUL: return l * r;

case DIV: assert(r!=0); return l/r;

default: throw new RuntimeException("## Error: BinaryRealSolution solution: l " + l + " op " + op + " r " + r);

} }

public void getVarsVals(Map<String,Object> varsVals) { left.getVarsVals(varsVals);

right.getVarsVals(varsVals); }

JPF đưa ra một lớp chuẩn để chuyển từ những định dạng của JPF sang một công cụ tìm lời giải nào đó. Đó là lớp trừu tượng ProblemGenenal, lớp này sẽ chứa các phương thức để chuyển các biểu thức nguyên tử hoặc ràng buộc nguyên tử sang định dạng của công cụ tìm lời giải, các lớp cụ thể sẽ được mở rộng từ những lớp này. Trong mở rông này đã có 3 cài đặt là ProblemChoco, ProblemIAsolver, ProblemCVC3, tương ứng với việc sử dụng: Choco, IAsolver, CVC3. Ví dụ để chuyển đổi sang định dạng của ràng buộc phép lớn hơn của IAsolver sẽ như sau:

Object gt(Object exp1, Object exp2){

return (String)exp1 + " > " + (String)exp2 + "; "; }

Việc mở rộng với Z3 cũng nên tuân thủ mô hình tích hợp với các công cụ tìm lời giái khác của JPF. Bây giờ ta phải tổ chức để sao cho chuyển ràng buộc từ JPF sang SMT-LIB. Một SMT-LIB sẽ có dạng như sau:

(benchmark:// Ten

:logic // kieu cua logic vi du so hoc tuyên tinh la: QF_LIA :extrafuns: // Khai bao bien

:formula :// Dinh nghia bieu thuc o day )

Trong đó formula chính là biểu thức cần phải chuyển ràng buộc của JPF sang, ví dụ về một biểu thức được định nghĩa bằng SMT LIB như sau.

(benchmark example :status sat

:logic QF_LIA

:extrafuns ((x1 Int) (x2 Int) (x3 Int) :formula (and (>= (- x1 x2) 1) (<= (- x1 x2) 3) (= x1 (+ (* 2 x3) 4)) )

Ta thiết kế một lớp ProblemZ3 ( tương tự như cách JPF tích hợp với các công cụ tìm lời giải: Choco, IASolver, CVC3) có nhiệm vụ chuyển ràng buộc sang dạng biểu thức ở trên..

Ví dụ chuyển đổi phép cho ràng buộc lớn hơn hoặc bằng >= sẽ như sau: Object geq(int value, Object exp){

return "(>= " + value + " " + (String)exp + ")"; }

Object geq(Object exp, int value){

}

Object geq(Object exp1, Object exp2){

return "(>= " + (String)exp1 + " " + (String)exp2 + ")"; }

Object geq(double value, Object exp){

return "(>= " + String.format(format,value) + " " + (String)exp + ")"; }

Object geq(Object exp, double value){

return "(>= " + (String)exp + " )" + String.format(format,value) + ")"; }

Sau đó ta sẽ thực hiện việc lưu định dạng trên ra file theo đúng như cấu trúc của ngôn ngữ SMT-LIB và gọi z3 thông qua dòng lệnh. Kết quả trả về sẽ được lưu trong đối tượng Result. Đối tượng này sẽ gồm một thuộc tính Boolean và một vector. Biến Boolean sẽ = true nếu câu trả lời là thỏa mãn, và false nếu câu trả lời là không thỏa mãn. Biến vector sẽ lưu trữ những cặp ( biến, giá trị) nếu nhận được câu trả lời là true.

public class Result {

public Boolean result; public Vector vresult; public Result() {

super();

vresult= new Vector(); }

public Vector getVresult() { return vresult;

}

public void setVresult(Vector vresult) { this.vresult = vresult;

}

public Boolean getResult() { return result;

public void setResult(Boolean result) { this.result = result;

} }

4.4 Thiết kế và cài đặt

Việc thiết kế và cài đăt phải tuân theo quy tắc mở rộng của JPF . Vì vậy, ta sẽ tạo một lớp là ProblemZ3 được sử dụng để chuyển ràng buộc từ JPF sang cấu trúc dữ liệu riêng. Tiếp theo ta sẽ tạo một gói (gói này sẽ hoạt động tương tự như thư viện Choco, Iasolver, hoặc CVC3). Gói này sẽ có nhiệm vụ chuyển cấu trúc dữ liệu từ Z3 ra file, sau đó chạy Z3 thông qua dòng lệnh với đầu vào là file vừa tạo ra, và lấy kết quả từ z3. Chuyển kết quả từ Z3 sang định dạng chung để lớp ProblemZ3 có thể sử dụng được. Hình 4-2 biểu diễn sơ đồ mức gói:

gov.nasa.jpf.symbc.numeric gov.nasa.jpf.symbc.z3wrapper

Z3

Một phần của tài liệu PHƯƠNG PHÁP SINH DỮ LIỆU KIỂM THỬ PHẦN MỀM DỰA TRÊN KỸ THUẬT KIỂM CHỨNG MÔ HÌNH (Trang 42 - 46)

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

(53 trang)
w