5 Thực nghiệm
2.16 Định nghĩa tiến trình địa phương
tiến trình là các cấu trúc đặc biệt của việc gán lại nhãn [3]. Hình 2.18 mơ tả định nghĩa của tiến trình kết hợp.
Ví dụ:
||S = a[1..3]:P.
||S = {a[1],a[2],a[3]}:P.
2.7.7 Tham số
Các tham số của tiến trình và tiến trình kết hợp phải có giá trị mặc định [3]. Tham số được định nghĩa ở Hình 2.19.
Ví dụ:
P(X=1) = (a[X] -> STOP).
Chương 2.Kiến thức cơ bản SequentialComposition: SeqProcessList ; BaseLocalProcess SeqProcessList: ProcessRef SeqProcessList ; ProcessRef ProcessRef:
ProcessIdent Argumentopt Argument: (ArgumentList) ArgumentList: Expression ArgumentList , Expression Hình 2.17: Định nghĩa thành phần tuần tự. CompositeDef:
kProcessIdent Paramopt=CompositeBody PriorityoptHidingopt.
CompositeBody:
PrefixLabeloptProcessRef Relabelopt
PrefixLabelopt(ParallelComposition)Relabelopt
forallRanges CompositeBody
ifExpressionthenCompositeBody
ifExpressionthenCompositeBodyelseCompositeBody PrefixLabel: ActionLabels: ActionLabels:: ActionLabels::ActionLabel: ParallelComposition: CompositeBody ParallelCompositionkCompositeBody Priority: »Set «Set Ranges: [ActionRange] Ranges[ActionRange] Hình 2.18: Định nghĩa thành phần tuần tự. 2.7.8 Phép gán lại nhãn và phép ẩn
Các tốn tử gán lại nhãn và ẩn có thể được áp dụng lên cả các tiến trình và tiến trình kết hợp [3]. Hình 2.20 mơ tả phép gán lại nhãn.
Ví dụ phép gán lại nhãn:
P/{ forall[i:1..3] {a[i]/x[i]}} tương đương với
P/{ a[1]/x[1], a[2]/x[2], a[3]/x[3] } Hình 2.21 định nghĩa phép ẩn.
Chương 2.Kiến thức cơ bản Param: (ParameterList) ParameterList: Parameter ParameterList , Parameter Parameter: ParameterIdent = Expression Hình 2.19: Định nghĩa tham số. Relabel: /{RelabelDefs} RelabelDefs: RelabelDef RelabelDefs, RelabelDef RelabelDef: ActionLabels / ActionLabels
forallIndexRanges{RelabelDefs}
Hình 2.20: Định nghĩa phép gán lại nhãn.
2.7.9 Property, Progress và Menu
Thuộc tính an tồn được định nghĩa bởi một tiến trình có tiền tố làproperty[3]. Hình 2.22 định nghĩa Property.
Hình 2.23 định nghĩa Progress.
Một Menu định nghĩa các thể loại tập hợp các hành động mà người dùng có thể điều khiển trong một hoạt cảnh [3]. Hình 2.24 định nghĩa Menu.
2.7.10 Biểu thức
Biểu thức của FSP là một tập con biểu thức của Java. Có một vài bất lợi khi các tốn tử tiến của FSP có ý nghĩa khác nhau khi được dùng trong ngữ cảnh của biểu thức. Cụ thể hơn, các phép tốn ưu tiên « và » có nghĩa là dịch trái và dịch
phải khi sử dụng trong một biểu thức. Tốn tử kết hợp song songk có ý nghĩa
logic khi sử dụng trong biểu thức. Tốn tử lựa chọn | có nghĩa là bit-wise or trong biểu thức. Và tốn tử gán lại nhãn / có nghĩa là phép chia trong biểu thức [3]. Hình 2.25, 2.26, 2.27 biểu diễn đặc tả biểu thức.
Biểu thức @(A, e) trả về giá trị nhãn của phần tử thứ e của tập A. Biểu thức #A trả về số lượng phần tử của tập A.
Chương 2.Kiến thức cơ bản Hiding: \Set @Set Hình 2.21: Định nghĩa phép ẩn. PropertyDef: propertyProcessDef Hình 2.22: Định nghĩa Property. 2.8 Ngơn ngữ lập trình hàm OCaml
2.8.1 Đặc trưng của OCaml
Trình biên dịch của OCaml [14] gán kiểu tĩnh cho dữ liệu trong chương trình và kiểm tra tại thời điểm biên dịch để đảm bảo rằng lỗi không xuất hiện . Kiểu của biến được suy diễn tự động trong suốt quá trình dịch bởi ngữ cảnh mà chúng xuất hiện trong chương trình. Vì vậy, kiểu của giá trị và kiểu trả về của hàm trong ngôn ngữ OCaml không cần đặc tả rõ, điều này sẽ làm cho dung lượng mã nguồn giảm xuống. Mã nguồn OCaml cũng có thể kiểm chứng được. Cơng cụ kiểm chứng tự động có thể kiểm tra mã nguồn OCaml và chứng thực rằng các kiểu được sử dụng hợp lệ. Công cụ kiểm tra sẽ đi sâu vào phân tích tĩnh chương trình ở một mức độ nào đó mà các ngơn ngữ lập trình khác (trừ Ada) hiện này chưa thể thực hiện được. Bên cạnh tính năng an tồn thì OCaml cịn có tốc độ thực thi nhanh. Trình biên dịch có khả năng tối ưu hóa mã nguồn nên sinh ra mã thực thi nhanh. OCaml đã phát triển hệ thống Module và thư viện chuẩn. Hệ thống Module cho phép lập trình viên viết các ứng dụng lớn. Một chương trình được viết bằng OCaml thường có kích thước bé hơn chính nó được viết bằng các ngôn ngữ khác. OCaml là một ngôn ngữ hết sức ngắn gọn, với các ngoại lệ và so khớp mẫu thì lập trình viên thường khơng phải viết nhiều mã nguồn như đã làm với các ngơn lập trình khác. Việc rút ngắn khối lượng mã nguồn sẽ giúp lập trình viên làm việc hiệu quả hơn, nhanh hơn và ít lỗi hơn. OCaml là một ngơn ngữ lập trình hàm nên việc học nhanh chóng OCaml là một điều khó khăn. Thơng thường, để rút ngắn gọn mã nguồn trong OCaml và để làm cho chương trình phát huy được hết sức mạnh của OCaml thì lập trình viên được khuyên nên sử dụng đệ quy, so khớp mẫu trong chương trình của mình. OCaml thừa hưởng phong cách lập trình của Meta Language. Vì vậy, người dùng phải mất một thời gian khá dài để hiểu được ngơn ngữ. Bên cạnh đó, cần có một số kiến thức lập trình và tư duy làm nền tảng.
Chương 2.Kiến thức cơ bản
ProgressDef:
progressProgressIdent Rangesopt=Set
progressProgressIdent Rangesopt=ifSetthenSet
Hình 2.23: Định nghĩa Progress.
MenuDef:
menuMenuIdent=Set
Hình 2.24: Định nghĩa Menu.
2.8.2 Cú pháp và ngữ nghĩa2.8.2.1 Biến 2.8.2.1 Biến
OCaml là ngôn ngữ hằng nên biến thực chất là giá trị được đặt tên và không thể thay đổi trong một phạm vi nào đó trong suốt q trình chạy [14]. Điều này có nghĩa là khi lập trình viên gán giá trị cho biến thì sau đó khơng thể thay đổi giá trị cho biến đó. OCaml cung cấp kiểu tham chiếu (mutable references), nó giống như là các con trỏ. Các biến tham chiếu này có thể thay đổi giá trị mà nó trỏ tới.
2.8.2.2 Kiểu dữ liệu cơ bản
Bảng 2.1: Các kiểu dữ liệu cơ bản của OCaml
Kiểu dữ liệu Mô tả
int Kiểu nguyên dương 31-bit float Kiểu số thực
bool Kiểu logic bao gồm true hoặc false char Kiểu kí tự
string Chuỗi ký tự unit Kiểu đặc biệt
OCaml cung cấp các kiểu dữ liệu cơ bản được liệt kê trong Bảng 2.1. Kiểu int chỉ sử dụng 32 bits tại vì nó sử dụng 1 bit để phân biệt giữa số nguyên và con trỏ. Nếu lập trình viên muốn sử dụng số ngun 32-bit thì có thể sử dụng Int32 hoặc sổ ngun 64-bit thì có thể sử dụng Int64.
2.8.2.3 Hàm
Hàm là một đối tượng dữ liệu nhận vào gồm có các tham số và trả về một đối tượng dữ liệu có kiểu [14]. Một hàm có thể nhận và trả về một kiểu dữ liệu OCaml hợp lệ bất kỳ, bao gồm kết quả trả về là một hàm khác. Hàm được định
Chương 2.Kiến thức cơ bản SimpleExpression: AdditiveExpr Expression: OrExpr Hình 2.25: Định nghĩa biểu thức.
nghĩa bằng cách sử dụng từ khóa let, f un hoặc f unction. Tuy nhiên, hàm u
cầu có ít nhất một tham số.
Hình 2.28 định nghĩa một hàm đơn giản nhất. Hàm có tên làmy f uncnhận
tham số là một kiểu unit và trả về giá trị là một kiểu int. Hàm được kết thúc
bằng hai dấu chấm phẩy. Hình 2.29 mơ tả cách gọi hàm trong OCaml. Hàm phải có duy nhất một kiểu trả về, mặc dù kiểu trả về có thể là kiểu đa hình. Kiểu mà hàm trả về sẽ được trình biên dịch tự động đưa ra. Trình biên dịch tìm kiểu thơng dụng nhất mà hàm có thể trả về và sau đó sử dụng kiểu đó.
2.8.2.4 Hàm mức cao
OCaml hỗ trợ hàm mức cao [14]. Điều này có nghĩa là hàm có thể nhận một hàm khác làm tham số. Sở dĩ OCaml làm được điều này vì OCaml xem hàm như là
các lớp dữ liệu cơ bản. Hình 2.30 là ví dụ minh họa hàmbiggernhận ba tham số
đầu vào. Tham số f đầu tiên là một hàm có hai tham số. Hai tham số cuối cùng
x,yđược xem như là tham số của tham số f.
2.8.2.5 Hàm nặc danh
Hàm nặc danh là hàm khơng có tên, vì vậy hàm khơng được gán bất kỳ một giá trị nào [14]. Hàm nặc danh rất hữu ích trong OCaml. Nhiều hàm sử dụng các hàm khác như là đối số và hàm nặc danh là cách dễ dàng khai báo và đưa vào làm tham số cho các hàm khác. Thông thường, khai báo hàm nặc danh bằng
cách sử dụng từ khóa f unhoặc f unction. Hàmcomparedùng để so sánh hai giá
trị trong việc sắp xếp một danh sách. Hàm nhận vào hai số nguyên và trả về giá trị là 1 nếu giá trị thứ hai bé hơn giá trị thứ nhất. Hàm trả về giá trị là 0 nếu giá trị thứ hai bằng giá trị thứ nhất và trả về giá trị là -1 nếu giá trị thứ hai lớn hơn giá trị thứ nhất. Hàmcomparecó thể được cài đặt riêng biệt rồi sử dụng nó. Tuy nhiên, với hàm nặc danh có thể giúp khai báo và sử dụng trực tiếp chính nó. Hình 2.31 mơ tả một hàm nặc danh.
Chương 2.Kiến thức cơ bản OrExpr: AndExpr OrExpr||AndExpr AndExpr: BitOrExpr
AndExpr&&BitOrExpr BitOrExpr: BitExclOrExpr BitOrExpr|BitExclOrExpr BitExclOrExpr: BitAndExpr BitExclOrExpr∧BitAndExpr BitAndExpr: EqualityExpr
BitAndExpr&EqualityExpr EqualityExpr: RelationalExpr EqualityExpr==RelationalExpr EqualityExpr!==EqualityExpr RelationalExpr: ShiftExpr RelationalExpr<ShiftExpr RelationalExpr<=ShiftExpr RelationalExpr>ShiftExpr RelationalExpr>=ShiftExpr ShiftExpr: AdditiveExpr ShiftExpr»AdditiveExpr ShiftExpr«AdditiveExpr
Hình 2.26: Định nghĩa biểu thức (tiếp).
2.8.2.6 Hàm đệ quy
Hàm đệ quy là một phần cực kỳ quan trọng của OCaml [14]. Hiệu suất và Kích thước mã nguồn của chương trình được cải tiến nhờ khả năng đệ quy đuôi trong OCaml. Hàm nặc danh khơng thể sử dụng đệ quy đi. Bởi vì hàm nặc danh khơng có tên nên khơng thể gọi hàm đó được. Hàm đệ quy được khai báo trong
OCaml bằng cách thêm từ khóa rec trước tên của hàm đó. Hàm đệ quy trong
OCaml là đệ quy đi nếu nó đảm bảo hai yêu cầu sau: hàm đệ quy không chứa try/with và giá trị trả về phải là giá trị khơng đổi. Ví dụ, hàm tính số Fibonacci khơng phải là hàm đệ quy đi [14]. Bởi vì, hàm tính số Fibonacci trả về giá trị là hàm u cầu tính giá trị Fibonacci tiếp theo. Hình 2.32 mơ tả một hàm đệ quy tính số Fibonacci.
2.8.2.7 So sánh mẫu
OCaml cung cấp một chức năng so sánh mẫu tương tự với cấu trúcSW ITCH...
Chương 2.Kiến thức cơ bản AdditiveExpr: MultiplicativeExpr AdditiveExpr+MultiplicativeExpr AdditiveExpr-MultiplicativeExpr MultiplicativeExpr: UnaryExpr MultiplicativeExpr*UnaryExpr MultiplicativeExpr\UnaryExpr MultiplicativeExpr%UnaryExpr UnaryExpr: BaseExpr +BaseExpr -BaseExpr !BaseExpr BaseExpr: IntegerLiteral Variable ConstantIdent ’ActionLabel #SetIdent @(SetIdent , Expression) (Expression)
Hình 2.27: Định nghĩa biểu thức (tiếp).
# l e t myfunc ( ) = 1 + 1 ; ;
v a l myfunc : u n i t −> i n t = <fun>
Hình 2.28: Ví dụ khai báo hàm.
giá trị đầu vào. Cấu trúc lệnh của so sánh mẫu được mơ tả ở Hình 2.33. Trình
biên dịch OCaml sẽ so sánh expression với các patternn để đưa ra quyết định
thực hiệnexpressionn tương ứng. Ví dụ so sánh mẫu được mơ tả ở Hình 2.34.
2.8.2.8 Đối tượng
OCaml là ngơn ngữ lập trình hàm được phát triển dựa trên ngơn ngữ CAML và có thêm chức năng hướng đối tượng [14]. OCaml cung cấp đầy đủ các nguyên lý của hướng đối tượng như: lớp, đối tượng, thừa kế, đa hình.
# myfunc 2 ; ;
− : i n t = 4
Chương 2.Kiến thức cơ bản # l e t b i g g e r f x y = f x y ; ; v a l b i g g e r : ( 'a −> 'b −> 'c ) −> 'a −> 'b −> 'c = <fun> # b i g g e r ( > ) 10 2 0 ; ; − : bool = f a l s e # b i g g e r ( < ) 10 2 0 ; ; − : bool = t r u e Hình 2.30: Ví dụ hàm mức cao. # L i s t . s o r t (fun x y −> i f x = y then −1 e l s e i f x < y then 1 e l s e 0 ) [ 1 ; 4 ; 9 ; 3 ; 2 ; 1 ] ; ; − : i n t l i s t = [ 9 ; 4 ; 3 ; 2 ; 1 ; 1 ] Hình 2.31: Ví dụ hàm nặc danh. # l e t r e c f i b n = i f ( n < 2 ) then 1 e l s e ( f i b ( n − 1 ) ) + ( f i b ( n − 2 ) ) ; ; v a l f i b : i n t −> i n t = <fun> # f i b 6 ; ; − : i n t = 13 Hình 2.32: Ví dụ hàm đệ quy.
match expression with | pattern1-> expression1 | pattern2-> expression2 ...
| patternn-> expressionn
Hình 2.33: Cấu trúc lệnh của so sánh mẫu.
# l e t f i = match i with
| o −> " Zero "
| 3 −> " Three "
| _ −> " Neith er zero nor t h r e e " ; ;
Chương 2.Kiến thức cơ bản
2.9 OCamllex và OCamlyacc
2.9.1 OCamllex
Ocamllex [15] là bộ sinh dùng để sinh ra chương trình phân tích đốn nhận các mẫu từ vựng trong tập tin đầu vào. Các biểu thức chính quy và các luật được đặc tả trong tập tin từ vựng. Ocamllex sẽ sinh ra tập tin mã nguồn OCaml dựa vào tập tin đặc tả này. Tập tin mã nguồn được sinh ra sẽ định nghĩa các hàm xử lý từ vựng [15]. Tập tin mã nguồn được dịch và liên kết lại để sinh ra tập tin có khả năng thực thi. Tập tin thực thi này khi chạy sẽ xử lý đầu vào của nó dựa vào các biểu thức chính quy. Khi nó tìm thấy một từ vựng nó sẽ thực thi đoạn mã nguồn OCaml tương ứng. Tập tin mã nguồn đặc tả từ vựng có đi mở rộng là .mll. Để biên dịch tập tin này sử dụng dòng lệnh:ocamllex∗.mll. Tập tin đặc tả từ vựng gồm có bốn thành phần: header,các định nghĩa, các luậtvàtrailer. Trong đó, các thành phầnheadervàruleslà cần thiết còn hai thành phần còn lại làrules vàtrailerlà tùy chọn. Cấu trúc tập tin đặc tả từ vựng được mơ tả như Hình 2.35. Hình 2.36 là ví dụ mơ tả một tập tin đặc tả từ vựng.
(* thành phần header *) { header }
(* thành phần định nghĩa *) let ident = regexp
let ...
(* thành phần luật *)
rule entrypoint [arg1... argn] = parse | pattern { action }
| ...
| pattern { action }
and entrypoint [arg1... argn] = parse ... and ... (* thành phần trailer *) { trailer } Hình 2.35: Cấu trúc tập tin đặc tả từ vựng. 2.9.2 OCamlyacc
Ocamlyacc [16] là bộ sinh dùng để sinh ra chương trình phân tích cú pháp bằng ngơn ngữ OCaml từ một tập tin đặc tả văn phạm phi ngữ cảnh. Chương trình OCaml này sẽ có chức năng phân tích cú pháp cho tập tin dữ liệu đầu vào tuân thủ theo văn phạm đó. Tập tin mã nguồn đặc tả cú pháp có đi mở rộng là
Chương 2.Kiến thức cơ bản { l e t num_lines = r e f 0 l e t num_chars = r e f 0 } r u l e count = parse
| '\n' { i n c r num_lines ; i n c r num_chars ; count ←-
l e x b u f } | _ { i n c r num_chars ; count l e x b u f } | e o f { ( ) } { l e t main ( ) = l e t l e x b u f = Lexing . from_channel s t d i n i n count l e x b u f ; P r i n t f . p r i n t f " # o f l i n e s = %d , # o f c h a r s = %d\n " !←- num_lines ! num_chars l e t _ = P r i n t e x c . p r i n t main ( ) } Hình 2.36: Ví dụ tập tin đặc tả từ vựng.
tả cú pháp gồm có bốn thành phần: header,khai báo Ocamlyacc, luật văn phạmvà
trailer. Cấu trúc tập tin đặc tả cú pháp được mơ tả như Hình 2.37.
%{
Header (mã nguồn OCaml) %}
Khai báo Ocamlyacc %%
Các luật văn phạm %%
trailer (có thể có mã nguồn OCaml)
Chương 3 AGTool
3.1 Giới thiệu AGTool
Phương pháp kiểm chứng mơ hình cịn gặp phải vấn đề "bùng nổ khơng gian trạng thái". Một giả thuyết được đặt ra là thay vì kiểm chứng trên tồn bộ hệ thống, chúng ta sẽ kiểm chứng từng thành phần của hệ thống đó. Với giả thuyết này thì phương pháp kiểm chứng giả định-đảm bảo có tiềm năng trong việc giải quyết bài toán của phương pháp kiểm chứng mơ hình. Để sử dụng được phương pháp kiểm chứng đảm bảo giả định, chúng ta cần sinh ra cho hệ thống một giả định (Assumption). Và AGTool [7] là một trong những công cụ dùng để thực hiện công việc sinh ra giả định đó. Hình 3.1 mơ tả tổng quan về AGTool.
Hình 3.1: Mơ hình cơng cụ kiểm chứng AGTool.
Các thành phần M1, M2 và thuộc tính Pcủa hệ thống được đặc tả bởi các
Chương 3.AGTool