Chương 4 KẾT QUẢ THỰC HIỆN CHƯƠNG TRÌNH
4.1. Cách sử dụng bộ kiểm chứng
Để sử dụng được bộ công cụ kiểm chứng ta làm theo các bước sau:
1) Truy cập vào màn hình hiển thị danh sách các bài tốn cần kiểm chứng bằng url http://phamvantuan.luanvan.com.
2) Trong màn hình danh sách bài toán, chọn 1 bài toán cần kiểm chứng thì sẽ hiển thị màn hình danh sách các mơ hình kiểm chứng của bài tốn được chọn. 3) Trong màn hình danh sách các mơ hình kiểm chứng, click vào link [Thực
hiện kiểm chứng] của các bộ kiểm chứng tương ứng thì chương trình sẽ mở ra 1 cửa sổ mới để thực hiện kiểm chứng và hiển thị kết quả.
Chú ý: Xem các màn hình ở trong Phụ lục B. 4.2. Kiểm chứng LDI đối với bài toán 1
Với bài toán và dữ liệu được mơ tả trong ví dụ 3.1 thực hiện kiểm chứng trên bộ kiểm chứng xây dựng thì ta được kết quả kiểm chứng như trong hình bên dưới.
Màn hình kết quả kiểm chứng gồm 2 phần:
– Phần 1, các giai đoạn thực hiện kiểm chứng thể hiện các bước chính trong q trình thực hiện kiểm chứng: từ cơng thức LDI được hiển thị các hệ số A = 0, B = , M = 5, các hệ số LDI tại các đỉnh của ôtômat Ldi(s1) = 1, Ldi(s2) = -1, và ôtômat được hiển thị dưới dạng đồ thị trong phần [1. Ơtơmat thành phần]. Từ ôtômat chương trình sẽ xây dựng đồ thị vùng đạt được nguyên trong phần [2. Đồ thị vùng nguyên đạt được:…], tiếp sau đó sẽ xây dựng đồ thị trọng số phục vụ kiểm chứng LDI hiển thị trên màn hình ở phần [3. Đồ thị trọng số kiểm chứng LDI:…].
– Phần 2, kết quả kiểm chứng: hiển thị kết quả kiểm chứng (ơtơmat có thỏa công thức LDI hay không) và thời gian thực hiện kiểm chứng.
4.3. Kiểm chứng LDI đối với bài tốn bếp ga
Dữ liệu mơ tả ơtơmat và công thức LDI trong file *.txt như sau:
60_U_0 2_NLeak NLeak##-1 Leak##19 2 NLeak#x1_x0_30_U#a#x1_1#Leak Leak#x1_x0_0_1#b#x1_1#NLeak
Chi tiết nội dung:
– 60_U_0: Lưu các hệ số của công thức LDI A = 60, B = (kí hiệu giá trị vơ
cùng là U) và M = 0.
– 2_NLeak: Thể hiện là ơtơmat có số đỉnh là 2 và đỉnh bắt đầu là NLeak.
– NLeak##-1: Biểu diễn thơng tin của đỉnh NLeak khơng có ràng buộc bất biến và có hệ số LDI ở đỉnh là -1.
– Leak##19: Biểu diễn thơng tin của đỉnh Leak khơng có ràng buộc bất biến và có hệ số LDI ở đỉnh là 19.
– 2: Dòng này thể hiện số phép chuyển trạng thái của ôtômat là 2.
– NLeak#x1_x0_30_U#a#x1_1#Leak: Thể hiện phép chuyển trạng thái thứ nhất e = <NLeak, x1 30, a, {x1}, Leak>.
– Leak#x1_x0_0_1#b#x1_1#NLeak: Thể hiện phép chuyển trạng thái thứ hai e = <Leak, x1 0 x1 1, b, {x1},NLeak>.
Thực hiện kiểm chứng trên bộ kiểm chứng, ta được kết quả như trong hình bên dưới. Nội dung thơng tin trong màn hình này cũng giống như trong màn hình của bài tốn 1.
Hình 4.2: kết quả kiểm chứng của bài toán bếp gas
4.4. Đánh giá về bộ công cụ kiểm chứng
Phần này chúng tôi đưa ra một số đánh giá về bộ công cụ kiểm chứng mà luận văn đã xây dựng được như sau:
– Bộ công cụ được xây dựng để thực hiện kiểm chứng cho các bài toán thuộc lớp các hệ thống được đặc tả bằng ôtômat thời gian và các tính chất thời khoảng của hệ thống (tính chất mong muốn của hệ thống) được biểu diễn bằng cơng thức khoảng tuyến tính (LDP) và bất biến khoảng tuyến tính (LDI) trong lơgic khoảng. Bộ cơng cụ sử dụng phương pháp duyệt đồ thị vùng đạt được nguyên. Trên cơ sở đồ thị vùng đạt được nguyên, và tính rời rạc hóa được của các công thức (LDP và LDI), các đồ thị trọng số phục vụ kiểm
chứng LDI (LDP) được xây dựng và thuật toán duyệt được tiến hành trên đồ thị này [2]. Đây là hướng đi mới được đề nghị trong Luận án Tiến sĩ của TS. Phạm Hồng Thái và hiện tại chưa có một cơng cụ hồn chỉnh nào được xây dựng và công bố để kiểm chứng cho lớp bài toán được đặc tả bằng ôtômat thời gian và các tính chất mong muốn được đặc tả bằng công thức LDI hoặc LDP.
– Hiện nay nhiều bộ kiểm chứng mơ hình thời gian thực ra đời tiêu biểu là HyTech, KRONOS, UPPAAL, v.v… Chẳng hạn, với bộ công cụ UPPAAL được công bố lần đầu tiên vào năm 1995 và sau đó nó được phát triển tiếp bởi sự hợp tác giữa trường đại học Uppsala và đại học Aalborg. UPPAAL được thiết kế để kiểm chứng cho một lớp con cơng thức lơgic cây tính toán thời gian (Timed Computational Tree Logic – TCTL) và ơtơmat thời gian [8]. Các tính chất được biểu diễn trong lôgic TCTL là tính chất thời điểm, nên UPPAAL không áp dụng được cho lớp bài tốn của luận văn nghiên cứu, đó là tính chất thời khoảng như “Tỉ lệ của tổng thời gian rị ga khơng vượt q một phần hai mươi của một đoạn thời gian quan sát bất kỳ không ngắn hơn một phút” trong bài toán bếp ga.
– Hiện tại tại thuật tốn kiểm chứng LDI có độ phức tạp cao, trong trường hợp xấu nhất thuật tốn có độ phức tạp hàm mũ, vì phải duyệt qua tất cả các chu trình của đồ thị. Trong phần 4.5 sẽ đề xuất hai giải pháp kỹ thuật để giảm thời gian duyệt đồ thị trọng số phục vụ kiểm chứng LDI.
4.5. Hướng cải tiến chương trình
Ý tưởng cải tiến, thực hiện xử lý song song để rút ngắn thời gian xử lý. Vì thuật tốn kiểm chứng LDI hiện tại đang sử dụng 1 vòng lặp để duyệt tuần tự cho mọi đỉnh của đồ thị là đỉnh xuất phát cho thủ tục duyệt mọi đường đi. Chúng ta thấy rằng thủ tục duyệt mọi đường đi với mỗi đỉnh xuất phát là hoàn toàn độc lập với nhau, do đó thay vì chờ duyệt các đỉnh xuất phát một cách tuần tự lần lượt từng đỉnh một thì ta sẽ cho duyệt song song đồng thời với tất cả các đỉnh của đồ thị là đỉnh xuất phát. Sau khi duyệt xong ta sẽ tổng hợp kết quả và đưa ra kết luận.
Với hướng cải tiến này thì thời gian kiểm chứng sẽ bằng thời gian duyệt mọi đường đi xuất phát từ một đỉnh có thời gian lâu nhất. Tức là với đồ thị có n đỉnh thì thời gian giảm trung bình được n lần trong trường hợp thời gian của thủ tục duyệt
Phương án triển khai, với ý tưởng trên thì chúng tơi đưa ra hai phương án để tối ưu lại chương trình như sau:
Phương án 1: Sử dụng kĩ thuật gửi yêu cầu không đồng bộ về server bằng ajax. Với phương án này thì sau khi thực hiện xong bước chuyển ôtômat sang đồ thị trọng số phục vụ kiểm chứng LDI thì chúng ta sẽ khơng thực hiện kiểm chứng LDI ngay mà sẽ thực hiện:
1) Lưu đồ thị trọng số LDI vào file.
2) Gửi định danh (ID) các đỉnh của đồ thị lên client.
3) Sử dụng ajax để gửi n request không đồng bộ về server với mỗi request là 1 đỉnh (có thể gửi một số đỉnh) của đồ thị lấy làm đỉnh bắt đầu, sau đó đọc đồ thị trọng số trong file ra để thực hiện duyệt.
4) Sau khi thực hiện xong tất cả các request thì tổng hợp lại kết quả và đưa ra kết luận. Ta có thể xử lý để nếu 1 request nào đó khơng thỏa LDI thì có thể đưa ra kết luận ln mà không cần chờ các đỉnh khác duyệt xong.
Phương án 2: Sử dụng kỹ thuật xử lý song song multi process được hỗ trợ trong các ngơn ngữ lập trình, trong PHP có hỗ trợ thư viện URL để làm công việc này. Theo phương án này ta chia công việc kiểm chứng ra thành n công việc nhỏ, mỗi công việc
sẽ thực hiện thủ tục duyệt traverse(vstart), sau khi xử lý xong tồn bộ n cơng việc thì
KẾT LUẬN
Với đề tài “Phân tích, thiết kế và cài đặt kiểm chứng một hệ thời gian thực”
luận văn này tập trung vào việc tìm hiểu các phương pháp đặc tả, các kỹ thuật để kiểm tra tính đúng đắn của hệ thống thời gian thực, trên cơ sở đó phân tích, thiết kế và cài đặt hệ chương trình kiểm chứng. Qua quá trình nghiên cứu luận văn đạt được một số kết quả nghiên cứu chính thể hiện trên những mặt sau:
1. Kết quả đạt được
– Luận văn đã trình bày tổng quan về hệ thời gian thực (gồm các khái niệm, phân loại, các đặc điểm của hệ thời gian thực) và kiến thức tổng quan về kiểm chứng mơ hình.
– Luận văn đã trình bày các phương pháp đặc tả một hệ thời gian thực, trong đó tìm hiểu đầy đủ về phương pháp đặc tả hệ thống bằng ôtômat và đặc tả các tính chất mong muốn của hệ thống bằng cơng thức LDI.
– Luận văn đã trình bày các kĩ thuật kiểm chứng mơ hình, bao gồm kĩ thuật phân vùng (region), miền (zone) và kĩ thuật rời rạc hóa.
– Luận văn đã tìm hiểu đầy đủ về các thuật tốn phục vụ viết bộ cơng cụ kiểm chứng mơ hình, bao gồm các thuật tốn chuyển ơtơmat sang đồ thị vùng đạt được nguyên, tạo đồ thị trọng số phục vụ kiểm chứng LDI từ đồ thị vùng đạt được nguyên và thuật toán duyệt đồ thị trọng số LDI để kiểm chứng công thức LDI. Luận văn cũng đưa được ra thuật tốn tạo ơtơmat song song từ một hệ các ôtômat thành phần.
– Cuối cùng luận văn đã xây dựng được bộ cơng cụ để thực hiện kiểm chứng mơ hình của hệ thống được đặc tả bằng ôtômat thời gian và các tính chất mong muốn của hệ thống đặc tả bằng công thức LDI. Bộ công cụ đã áp dụng được cho hệ thống bếp ga và công thức LDI ở dạng tổng quát.
2. Hướng nghiên cứu phát triển
Kiểm chứng mơ hình đối với hệ thời gian thực là một lĩnh vực khó và phức tạp địi hỏi phải có nhiều thời gian và bỏ ra nhiều cơng sức mới có thể tìm hiểu sâu sắc về nó, nên ngồi những kết quả đã đạt được ở trên thì trong thời gian tới luận văn có thể tiếp tục hồn thiện và nghiên cứu để giải quyết các vấn đề còn tồn tại sau:
– Thuật toán kiểm chứng LDI đang có độ phức tạp hàm mũ nên khi số lượng trạng thái tăng lên chương trình chạy rất chậm. Do vậy, cần nghiên cứu để cải tiến làm giảm độ phức tạp xuống hoặc tìm hiểu thêm các kĩ thuật mới.
– Xây dựng bộ cơng cụ hồn chỉnh để kiểm chứng cho LDP, LDI. Hiện tại bộ công cụ đang được xây dựng trên nền web và các chức năng cũng chưa đầy đủ.
TÀI LIỆU THAM KHẢO Tiếng Việt
[1] Hoàng Minh Sơn (2006), Hệ Thời gian thực và điều khiển thời gian thực, Tạp chí
TĐHNN (tạp chí điện tử).
[2] Phạm Hồng Thái (2005), Kiểm chứng tính chất thời gian thực bằng thuật toán,
Luận án Tiến sỹ, Hà Nội. Tiếng Anh
[3] R. Alur and D.L. Dill (1994), "A Theory of Timed Automata", Theoretical
Computer Science, pp. 183-235.
[4] Rajeev Alur (1999), "Timed Automata", Proceedings of 11th International
Conference on Computer-Aided Verification, LNCS 1633, pp. 1-22, Springer-
Verlag.
[5] Changil Choe1, Dang Van Hung2, and Song Han3, 1,3Faculty of Mathematics, Kim Il Sung University, D.P.R.K, 2Faculty of Information Technology, Vietnam
National University, Vietnam (2012), Towards Approximate Model Checking DC
and PDC Specifications, pp. 3-4.
[6] Jame W.S.Liu (2000), Real time system, Prentice Hall.
[7] Z. Chaochen, C. Hoare, and A. Ravn (1991). A Calculus of Duration.
Information Processing Letters, 5(40): 269-276.
[8] Johan Bengtsson and Wang Yi (2004), Timed Automata: Semantics, Algorthms
PHỤ LỤC
Phụ lục A. Một số mơ đun chương trình của bộ kiểm chứng
Trong phần này chúng tôi liệt kê mã nguồn một số hàm chính của chương trình gồm các hàm: tạo ôtômat hợp song song, tạo đồ thị vùng đạt được nguyên, khử cung vô hạn, tạo đồ thị trọng số phục vụ kiểm chứng LDI và kiểm chứng công thức LDI.
Tạo ôtômat hợp song song
Các hàm trong phần này thực hiện chức năng tạo ra 1 ôtômat song song đạt được từ 1 hệ các ôtômat thành phần. Phần này gồm 2 hàm được viết trong class
OtomatLogic: Hàm thứ nhất createOtomatParallel($aryOtomat) thực hiện tạo ra 1
ôtômat song song từ nhiều ôtômat thành phần, trong hàm này gọi đến hàm thứ 2
createOtomatParallelFrom2Otomat($aryOtomat1, $aryOtomat2) để thực hiện tạo 1
ôtômat song song đạt được từ 2 ôtômat thành phần.
public function createOtomatParallel($aryOtomat) { //TH He co 1 otomat
if (count($aryOtomat) == 1) { return current($aryOtomat); }
//TH He co >= 2 otomat
for ($i = 1; $i < count($aryOtomat); $i++) { if ($i == 1) { $aryAutomataParallel = $this->createOtomatParallelFrom2Otomat($aryOtomat[$i], $aryOtomat[$i+1]); } else { $aryAutomataParallel = $this->createOtomatParallelFrom2Otomat($aryAutomataParallel, $aryOtomat[$i+1]); } } return $aryAutomataParallel; }
public function createOtomatParallelFrom2Otomat($aryOtomat1, $aryOtomat2) { $aryLocation1 = $aryOtomat1['aryLocation']; $aryLocation2 = $aryOtomat2['aryLocation']; $aryTransition1 = $aryOtomat1['aryTransition']; $aryTransition2 = $aryOtomat2['aryTransition']; $arySyschr = array();
$aryAdj1 = $aryAdj2 = array();
$this->getLocationAdj($aryAdj1, $aryAdj2, $arySyschr, $aryTransition1, $aryTransition2); $init1 = $aryOtomat1['init']; $init2 = $aryOtomat2['init']; $aryClock = array_unique(array_merge($aryOtomat1['clocks'], $aryOtomat2['clocks'])); //Khoi tao $aryStackPath = array();
$aryStackPath[] = $this->getLocationOtomatParallel($init1, $init2, $aryAdj1[$init1], $aryAdj2[$init2]);
$aryLocation = $aryTransition = array(); //Add Location $aryInvar = array(); $res = $this->createGuardOfOtomatParallet($aryInvar, $aryLocation1[$init1]['invar'], $aryLocation2[$init2]['invar']); $w = $aryLocation1[$init1]['c'] + $aryLocation2[$init2]['c']; $aryLocation["{$init1},{$init2}"] = array( 'invar' => $aryInvar, 'c' => $w ); $aryCheck = array(); $aryCheck["{$init1},{$init2}"] = 1; while (count($aryStackPath) > 0) { $aryGuard = array(); $loc1_to = $loc2_to = null; $label = '';
$this->getSuccLocation($loc1, $loc2, $loc1_to, $loc2_to, $label, $aryStackPath, $arySyschr);
if ($loc1_to == null || $loc2_to == null) { array_pop($aryStackPath); continue; } $locNameFrom = "{$loc1},{$loc2}"; $locNameTo = "{$loc1_to},{$loc2_to}"; //Add Location $aryInvar = array(); $res = $this->createGuardOfOtomatParallet($aryInvar, $aryLocation1[$loc1_to]['invar'], $aryLocation2[$loc2_to]['invar']); if (!isset($aryLocation[$locNameTo]) && $res) {
$w = $aryLocation1[$loc1_to]['c'] + $aryLocation2[$loc2_to]['c']; $aryLocation[$locNameTo] = array( 'invar' => $aryInvar, 'c' => $w ); } //Add transition
$guard1 = $guard2 = array(); $aryReset = array();
foreach ($aryTransition1 as $k1 => $transition1) {
if (strcmp($loc1, $transition1['loc_name_from']) != 0) { continue;
}
foreach ($aryTransition2 as $k2 => $transition2) {
if (strcmp($loc2, $transition2['loc_name_from']) != 0) { continue;
}
if (strcmp($loc1, $loc1_to) == 0 && strcmp($loc2_to, $transition2['loc_name_to']) == 0) {
$aryReset = $transition2['reset']; $guard2 = $transition2['guard']; break 2;
} elseif (strcmp($loc2, $loc2_to) == 0 && strcmp($loc1_to, $transition1['loc_name_to']) == 0) {
$aryReset = $transition1['reset']; $guard1 = $transition1['guard']; break 2;
} elseif (strcmp($loc2_to, $transition2['loc_name_to']) == 0 && strcmp($loc1_to, $transition1['loc_name_to']) == 0) {
$guard1 = $transition1['guard']; $guard2 = $transition2['guard'];
$aryReset = $transition1['reset'];
if (is_array($transition2['reset']) && count($transition2['reset']) > 0) { foreach ($transition2['reset'] as $k => $v) { $aryReset[$k] = $v; } } break 2; } } } $aryGuard = array();
$res = $this->createGuardOfOtomatParallet($aryGuard, $guard1, $guard2); if ($res) { $aryTransition[] = array( 'loc_name_from' => $locNameFrom, 'loc_name_to' => $locNameTo, 'label' => $label, 'reset' => $aryReset, 'guard' => $aryGuard, ); } if (!isset($aryCheck[$locNameTo])) {
$aryStackPath[] = $this->getLocationOtomatParallel($loc1_to, $loc2_to, $aryAdj1[$loc1_to], $aryAdj2[$loc2_to]);
} }
//Khoi tao Otomat Parallel $aryOtomatParallel = array(
'init' => $aryOtomat1['init'] . ',' . $aryOtomat2['init'], 'numLocation' => count($aryLocation), 'numTransition' => count($aryTransition), 'clocks' => $aryClock, 'aryLocation' => $aryLocation, 'aryTransition' => $aryTransition, );
$this->logger->log(" aryOtomatParallel = " . print_r($aryOtomatParallel, true)); return $aryOtomatParallel;
}
Tạo đồ thị vùng đạt được nguyên
public function createRegionGraph($aryOtomat, $aryConstantMaxK) { $this->logger->log( " Begin method: " . __METHOD__ . "()"); $maxK = max($aryConstantMaxK); $locationStart = $aryOtomat['init']; $aryLocation = $aryOtomat['aryLocation']; $aryTransition = $aryOtomat['aryTransition']; $aryClock = $aryOtomat['clocks'];
//Khoi tao so dinh hien tai
$this->graphRegion['num_vertex'] = 1; //Khoi tao so canh hien tai
$this->graphRegion['num_edge'] = 0; //Nhap dinh <s0, (0,0)>
$region0 = join(',', array_fill(0, count($aryClock), 0)); $regionK = join(',', array_fill(0, count($aryClock), 'U')); //Id region
$regionId = 1;
$vertex0 = $this->createVertexRegion($locationStart, $region0); $this->graphRegion['aryVertex'][$regionId] = array(
'vertex' => $vertex0, 'loc_name' => $locationStart, 'region' => $region0, 'ldi_c' => $aryLocation[$locationStart]['c'], 'visited' => 0, );
//Khoi tao tap canh rong
$this->graphRegion['aryEdge'] = array();
while (true) {
//lay dinh chua tham trong V
$vertex = $this->getVertexNotVisited(); //neu tat ca cac dinh da tham thi ket thuc if ($vertex === false) {
break ; }
//Dinh s trong Otomat
$loc_name_from = $vertex['loc_name']; $region = $vertex['region'];
$vertex_from = $vertex['vertex']; $id_from = $vertex['id'];
//Loop Transition cua Otomat
foreach ($aryTransition as $transition) {
//Neu ton tai phep chuyen e = <s, g, a, λ, s'>
if (strcmp($loc_name_from, $transition['loc_name_from']) == 0) { $loc_name_to = $transition['loc_name_to'];
//Xac dinh xem co chuyen dc khong for ($d = 0; $d <= $maxK + 1; $d++) {
$regionSucc = $this->creatRegionPlus($region, $d, $aryConstantMaxK);
//Kiem tra dieu kien I(s)
if (!$this->checkGuard($regionSucc, $aryLocation[$loc_name_from]['invar'])) {
continue; }
//Kiem tra dieu kien rang buoc g if (!$this->checkGuard($regionSucc, $transition['guard'])) { continue; } //Reset clock $regionTo = $this->resetRegionClock($regionSucc, $transition['reset']);
//Kiem tra dieu kien I(s') sau khi reset if (!$this->checkGuard($regionTo, $aryLocation[$loc_name_to]['invar'])) {
continue; }
//Dat lai gia tri trong mien theo qui uoc
$regionTo = $this->reformatRegion($regionTo, $aryConstantMaxK);
//Kiem tra dinh nay da co chua
$vertex_to = $this->createVertexRegion($loc_name_to, $regionTo);
$vertexId = $this->getVertex($vertex_to);
//Neu chua co thi bo sung if ($vertexId == 0) { $regionId++; $this->addVertexRegion($loc_name_to, $regionTo, $aryLocation[$loc_name_to]['c'], $regionId); $id_to = $regionId; } else { $id_to = $vertexId; }
//Kiem tra va bo sung cung neu chua co if (!$this->isExistEdge($id_from, $id_to)) { $durationLow = $durationUp = 0;