25/05/2018, 00:05

Otomat đẩy xuống ( PDA : PUSHDOWN AUTOMATA)

Nội dung chính: Trong chương này, chúng ta khảo sát một dạng mô hình ôtômát khác, có khả năng nhận diện được lớp ngôn ngữ mà văn phạm phi ngữ cảnh sinh ra - ôtômát đẩy xuống (PDA) - với sự bổ sung thêm của Stack đóng vai ...

Nội dung chính:

Trong chương này, chúng ta khảo sát một dạng mô hình ôtômát khác, có khả năng nhận diện được lớp ngôn ngữ mà văn phạm phi ngữ cảnh sinh ra - ôtômát đẩy xuống (PDA) - với sự bổ sung thêm của Stack đóng vai trò như một bộ giữ nhớ trong quá trình ôtômát thực hiện các phép chuyển để nhận dạng ngôn ngữ. Tiếp theo đó, mối quan hệ tương đương giữa hai cơ chế - ôtômát đẩy xuống và CFG- dùng biểu diễn cho lớp văn phạm phi ngữ cảnh cũng sẽ được nêu ra và chứng minh chặt chẽ.

Mục tiêu cần đạt :

Cuối chương này, sinh viên có thể:

Thiết kế PDA chấp nhận một ngôn ngữ phi ngữ cảnh cho trước bằng Stack rỗng hay trạng thái kết thúc.

Chuyển một PDA chấp nhận ngôn ngữ bằng trạng thái kết thúc sang PDA chấp nhận ngôn ngữ bằng Stack rỗng và ngược lại.

Xây dựng NPDA chấp nhận ngôn ngữ sinh ra từ một CFG.

Viết văn phạm phi ngữ cảnh sinh ra lớp ngôn ngữ được chấp nhận bởi một NPDA cho trước.

Kiến thức cơ bản:

Để tiếp thu tốt nội dung của chương này, sinh viên cần nắm vững các tính chất của lớp ngôn ngữ phi ngữ cảnh; cơ chế đoán nhận ngôn ngữ của dạng máy trừu tượng ôtômát và các thành phần bắt buộc của chúng; …

Tài liệu tham khảo :

V.J. Rayward-Smith – A First course in Formal Language Theory (Second Editor) – McGraw-Hill Book Company Europe – 1995 (Chapter 6 : Pushdown Automata )

John E. Hopcroft, Jeffrey D.Ullman – Introduction to Automata Theory, Languages and Computation – Addison – Wesley Publishing Company, Inc – 1979 (Chapter 5 : Pushdown Automata )

Hồ Văn Quân – Giáo trình lý thuyết ôtômát và ngôn ngữ hình thức – Nhà xuất bản Đại học quốc gia Tp. Hồ Chí Minh – 2002.

Copy right by David Matuszek - NPDAs and CFGs:

http://www.netaxs.com/people/nerp/automata/npda-cfg0.html

Như ta đã biết, lớp các ngôn ngữ chính quy được sinh từ văn phạm chính quy, đồng thời cũng được đoán nhận bởi các ôtômát hữu hạn (đơn định hoặc không đơn định). Trong phần này, chúng ta lại thấy một điều tương tự là lớp ngôn ngữ phi ngữ cảnh, được sinh ra từ văn phạm phi ngữ cảnh, cũng được đoán nhận bởi một loại ôtômát khác - gọi là ôtômát đẩy xuống (PDA).

Có một điều khác biệt là ở đây, chỉ có dạng ôtômát đẩy xuống không đơn định (NPDA) mới có thể đủ mạnh để đoán nhận lớp ngôn ngữ phi ngữ cảnh, còn dạng đơn định (DPDA) chỉ cho phép đoán nhận một tập con thực sự của lớp ngôn ngữ này. Tuy nhiên, tập con đó cũng bao gồm phần lớn các ngôn ngữ lập trình.

Mô tả PDA

Ôtômát đẩy xuống thực chất là một ôtômát với sự điều khiển cả hai: băng nhập và Stack (bộ đẩy xuống). Về cơ bản, nó vẫn giữ tất cả các thành phần của một ôtômát hữu hạn, với sự bổ sung thêm một ngăn xếp làm việc (Stack) đóng vai trò như một bộ giữ nhớ, nhờ đó mà khả năng ghi nhớ của ôtômát được tăng thêm. Stack xem như là một chồng đĩa, vì vậy cái đặt vào sau sẽ lấy ra trước (LIFO).

Với sự mở rộng này ôtômát đẩy xuống có thể chấp nhận cả các biểu thức không chính quy. Chẳng hạn tập hợp L = {wcwR | w ∈ (0+1)*} (với wR là chuỗi đảo ngược của chuỗi w) là một ngôn ngữ phi ngữ cảnh sinh bởi văn phạm S → 0S0 | 1S1 | c và nó không thể được chấp nhận bởi bất kỳ một ôtômát hữu hạn nào.

Hình 6.1 - Mô tả một PDA

Để chấp nhận ngôn ngữ L như trên ta dùng bộ điều khiển có hai trạng thái q1, q2 và một Stack trên đó ta đặt các đĩa xanh (B), vàng (Y), đỏ (R). Thiết bị sẽ thao tác theo các quy tắc sau đây:

1) Máy sẽ bắt đầu với một đĩa đỏ ở trên Stack và bộ điều khiển ở trạng thái q1.

2) Nếu 0 được đưa vào thiết bị thì ta đặt một đĩa xanh vào Stack. Nếu đưa 1 vào thiết bị ở trạng thái q1 thì ta đặt một đĩa vàng vào Stack. Cả hai trường hợp thiết bị không thay đổi trạng thái.

3) Nếu c được đưa vào thiết bị ở trạng thái q1 thì thiết bị đổi trạng thái sang q2 và không thay đổi Stack.

4) Nếu 0 được đưa vào thiết bị ở trạng thái q2 và đỉnh Stack là đĩa màu xanh thì đĩa được lấy ra. Nếu 1 đưa vào thiết bị ở trạng thái q2 và đĩa vàng tại đỉnh Stack thì ta loại bỏ đĩa này. Trạng thái q2 không thay đổi.

5) Nếu thiết bị ở trạng thái q2 và đĩa đỏ tại đỉnh Stack ta loại bỏ đĩa này không cần ký hiệu nhập.

6) Ngoài các trường hợp trên thì thiết bị không thay đổi.

Các quy tắc trên được tóm tắt như trong bảng sau:

Hình 6.2 - Mô tả hoạt động của PDA chấp nhận ngôn ngữ {wcwR |w∈ (0+1)*}

Một chuỗi được chấp nhận bởi thiết bị nếu nó đã đọc duyệt qua đến hết chuỗi đồng thời với Stack trở về trạng thái rỗng.

Nhận xét: Nhờ Stack có khả năng lưu giữ một số bất kỳ các ký hiệu mà PDA có thể nhớ nửa phần đầu của chuỗi (w) cho tới khi gặp ký hiệu phân cách c, cho dù chuỗi có độ dài lớn đến bao nhiêu. Và sau đó, các ký hiệu này được đem ra để so sánh dần với phần chuỗi ngược còn lại (wR). Một ôtômát hữu hạn không có được khả năng ghi nhớ đó.

Định nghĩa

Ôtômát đẩy xuống có một bộ điều khiển hữu hạn và một Stack. Stack chứa một chuỗi các ký hiệu thuộc một bộ chữ cái nào đó. Ký hiệu bên trái nhất của chuỗi xem như ký hiệu tại đỉnh Stack. PDA không đơn định nếu như có một số hữu hạn các lựa chọn phép chuyển trong mỗi lần chuyển.

Phép chuyển sẽ có hai kiểu:

- Kiểu thứ nhất phụ thuộc vào ký hiệu nhập, tức là với một trạng thái, một ký hiệu tại đỉnh Stack và một ký hiệu nhập; PDA sẽ lựa chọn trạng thái kế tiếp và một chuỗi các ký hiệu thay thế trên Stack, đầu đọc dịch đi sang phải một ký hiệu.

- Kiểu thứ hai không phụ thuộc vào ký hiệu nhập, gọi là ε - dịch chuyển : tương tự như kiểu thứ nhất, chỉ ngoại trừ là ký hiệu nhập không được dùng và đầu đọc không dịch chuyển sau khi chuyển trạng thái. Thực chất, bước chuyển đặc biệt này là một sự tạm ngừng quan sát trên băng nhập để sắp xếp lại các ký hiệu trong ngăn xếp.

Có hai cách để định nghĩa ngôn ngữ chấp nhận bởi ôtômát đẩy xuống:

- Ngôn ngữ được chấp nhận bởi Stack rỗng: gồm tất cả các input mà sau một chuỗi các phép chuyển trạng thái làm cho ôtômát dẫn tới Stack rỗng.

- Ngôn ngữ được chấp nhận bởi trạng thái kết thúc: ta thiết kế một số trạng thái kết thúc, khi đó ngôn ngữ chấp nhận bởi ôtômát có thể định nghĩa gồm tất cả các input mà có một chuỗi các phép chuyển làm cho ôtômát dẫn tới một trong những trạng thái kết thúc.

Ta có thể thấy hai cách định nghĩa cho sự chấp nhận chuỗi này là tương đương nhau trong mọi trường hợp, có nghĩa là nếu một tập hợp được chấp nhận bởi Stack rỗng của một PDA nào đó thì cũng sẽ được chấp nhận bằng trạng thái kết thúc trên một PDA khác, và ngược lại. Thiết kế PDA chấp nhận chuỗi bằng trạng thái kết thúc thường phổ biến hơn, nhưng sẽ dễ dàng hơn để chứng minh nguyên lý cơ bản của PDA khi thiết kế PDA chấp nhận chuỗi bằng Stack rỗng. Nguyên lý này được phát biểu như sau: Một ngôn ngữ được chấp nhận bởi PDA khi và chỉ khi nó là một ngôn ngữ phi ngữ cảnh.

Một cách hình thức, ta định nghĩa:

Định nghĩa : Một ôtômát đẩy xuống M là một hệ thống M (Q, Σ, Γ, δ, q0, Z0, F), trong đó :

1) Q là tập hữu hạn các trạng thái

2) Σ là bộ chữ cái gọi là bộ chữ cái nhập

3) Γ là bộ chữ cái gọi là bộ chữ cái Stack

4) δ: hàm chuyển ánh xạ từ Q × (Σ size 12{ union } {}{ε}) × Γ → tập con hữu hạn của Q × Γ*

5) q0 là trạng thái khởi đầu

5) Z0 là một chữ cái riêng của Stack gọi là ký hiệu bắt đầu trên Stack

6) F ⊆ Q là tập các trạng thái kết thúc

(Trong trường hợp PDA được thiết kế chấp nhận ngôn ngữ bằng Stack rỗng thì tập hợp F = ∅)

Trừ khi ta dùng các ký hiệu khác, ta quy ước dùng chữ nhỏ gần đầu bảng chữ cái để chỉ các ký hiệu nhập, các chữ nhỏ cuối bảng chữ cái để chỉ các chuỗi nhập. Các chữ hoa và chữ Hy lạp chỉ ký hiệu và chuỗi ký hiệu Stack.

Sự dịch chuyển

Hàm chuyển phụ thuộc ký hiệu nhập :

δ(q, a, Z) = {(p1, γ size 12{γ} {}1), (p2, γ size 12{γ} {}2), ..., (pm, γ size 12{γ} {}m)}

trong đó q và pi, 1 ≤ i ≤ m, là các trạng thái thuộc tập Q, a ∈ Σ, Z là một ký hiệu Stack và γ size 12{γ} {}i ∈ Γ*, 1 ≤ i ≤ m, là PDA ở trạng thái q với ký hiệu nhập a và ký hiệu Z tại đỉnh Stack, nó đi vào một trạng thái pi nào đó thay Z bằng γ size 12{γ} {}i và dịch chuyển đầu đọc đi một ký hiệu. Ta quy ước rằng ký hiệu bên trái nhất của γ size 12{γ} {}i sẽ là ký hiệu được thay cao nhất trên Stack (nghĩa là nó nằm tại đỉnh Stack mới) và ký hiệu bên phải nhất của γ size 12{γ} {}i là ký hiệu được thay thấp nhất trong Stack. Chú ý rằng không được phép chọn pi và γ size 12{γ} {}j với i ≠ j tại một bước chuyển nào đó.

Hàm chuyển không phụ thuộc ký hiệu nhập :

δ(q, ε, Z) = {(p1, γ size 12{γ} {}1), (p2, γ size 12{γ} {}2), ..., (pm, γ size 12{γ} {}m)}

trong đó q là trạng thái mà PDA đang giữ, độc lập với ký hiệu nhập, PDA đi vào trạng thái pi thay Z bởi γ size 12{γ} {}i với 1 ≤ i ≤ m. Trong trường hợp này đầu đọc không dịch chuyển.

Thí dụ 6.1 : Mô tả dưới đây cho PDA chấp nhận ngôn ngữ {wcwR | w ∈ (0+1)*} bằng Stack rỗng.

M ({q1, q2}, {0, 1, c}, {R, B, Y}, d, q1, R, ∅ size 12{ emptyset } {} )

1) d(q1, 0, R) = {(q1, BR)}

2) d(q1, 1, R) = {(q1, YR)}

3) d(q1, 0, B) = {(q1, BB)}

4) d(q1, 1, B) = {(q1, YB)}

5) d(q1, 0, Y) = {(q1, BY)}

6) d(q1, 1, Y) = {(q1, YY)}

7) d(q1, c, R) = {(q2, R)}

8) d(q1, c, B) = {(q2, B)}

9) d(q1, c, Y) = {(q2, Y)}

10) d(q2, 0, B) = {(q2, e)}

11) d(q2, 1, Y) = {(q2, e)}

12) d(q2, e, R) = {(q2, e)}

Hình 6.3 - Mô tả PDA chấp nhận wcw R bằng Stack rỗng

Chú ý rằng mỗi phép chuyển PDA sẽ viết lên đỉnh Stack một chuỗi  có độ dài 2. Chẳng hạn d(q1, 0, R) = {(q1, BR)}. Nếu  có độ dài bằng 1 thì PDA đơn giản là thay ký hiệu tại đỉnh Stack và không làm thay đổi độ dài Stack. Nếu  bằng ε thì PDA loại bỏ (Pop) phần tử tại đỉnh Stack. Chẳng hạn d(q2, e, R) = {(q2, e)} nghĩa là PDA ở trạng thái q2 với R ở đỉnh Stack thì PDA xóa R độc lập với ký hiệu nhập, trong trường hợp này đầu đọc không dịch chuyển, điều này có nghĩa là PDA không yêu cầu còn một ký hiệu nào trên chuỗi nhập.

Hình thái (ID : Instantaneous Descriptions)

Để hình thức hóa cấu hình của một PDA với một PDA cụ thể, ta định nghĩa một hình thái (ID). ID phải ghi nhớ trạng thái và nội dung của Stack. ID là một bộ ba (q, w, ), trong đó q là trạng thái, w là chuỗi nhập và  là chuỗi các ký hiệu Stack.

Nếu M (Q, Σ, Γ, δ, q0, Z0, F) là một PDA, ta nói :

(q, aw, Zα) ⊢M (p, w, βα) nếu δ(q, a, Z) chứa (p, β)

Lưu ý a có thể là một ký hiệu trong input hoặc ε. Chẳng hạn với PDA mô tả như trên, ta có (q1, BY) ∈ d(q1, 0, Y), suy ra rằng (q1, 011, YYR) ⊢ (q1, 11, BYYR).

Ta dùng ký hiệu ⊢*M cho bao đóng phản xạ và bắt cầu của ⊢M, tức là : I ⊢* I đối với mỗi ID I, và I ⊢M J và J ⊢*M K thì I ⊢*M K. Ta viết I ⊢i K nếu ID I trở thành K sau chính xác i bước chuyển. Chữ chỉ số dưới M trong các ky 1hiệu ⊢M, ⊢iM và ⊢*M có thể được bỏ qua khi M đã được xác định.

Ngôn ngữ chấp nhận bởi PDA

Với PDA M (Q, Σ, Γ, δ, q0, Z0, F), ta định nghĩa :

Ngôn ngữ được chấp nhận bởi trạng thái kết thúc là:

L (M) = {w | (q0, w, Z0) ⊢* (p, ε, γ size 12{γ} {}) với p ∈ F và γ size 12{γ} {}∈ Γ*}

Ngôn ngữ được chấp nhận bởi Stack rỗng là :

N(M) = {w | (q0, w, Z0) ⊢* (p, ε, ε) với p ∈ Q}.

Khi có sự chấp nhận bằng Stack rỗng thì tập trạng thái kết thúc là không còn cần thiết vì vậy ta ký hiệu tập trạng thái kết thúc F là ∅ size 12{ emptyset } {}.

Thí dụ 6.2 : Các phép chuyển hình thái của PDA chấp nhận chuỗi 001c100 thuộc ngôn ngữ {wcwR |w ∈ (0+1)*} bằng Stack rỗng như sau :

(q1, 001c100, R) ⊢ (q1, 01c110, YR) ⊢ (q1, 1c110, YYR) ⊢ (q1, c100, BYYR) ⊢

(q2, 100, BYYR) ⊢ (q2, 00, YYR) ⊢ (q2, 0, YR) ⊢ (q2, ε, R) ⊢ (q2, ε, ε) : Chấp nhận

Nhận xét : Trong ví dụ thiết kế PDA chấp nhận ngôn ngữ {wcwR |w ∈ (0+1)*} bằng Stack rỗng như trên, ta thấy các giá trị hàm chuyển của nó luôn là là đơn trị. Tại mỗi thời điểm từ một trạng thái trong bộ điều khiển, có thể đọc vào hoặc không đọc một ký hiệu trên băng nhập, với một ký hiệu tại đỉnh Stack, chỉ có một giá trị xác định bước chuyển kế tiếp. Vì thế, ta gọi dạng PDA này là ôtômát đẩy xuống đơn định - DPDA.

PDA không đơn định (NPDA)

Thí dụ 6.3 : Thiết kế PDA chấp nhận ngôn ngữ {wwR | w ∈ (0+1)*} bằng Stack rỗng.

Rõ ràng ta thấy khi không có sự hiện diện của ký hiệu c ở giữa chuỗi nhập để xác định thời điểm bộ điều khiển có thể chuyển từ trạng thái q1 sang trạng thái q2, thì vấn đề sẽ trở nên phức tạp hơn khi cần phải quyết định đâu là ký hiệu bắt đầu cho chuỗi ngược (wR) ? Ở mỗi thời điểm mà bộ điều khiển đọc thấy hai ký hiệu liên tiếp giống nhau trong chuỗi nhập thì bắt buộc nó phải đoán thử cả hai khả năng cho ký hiệu thứ hai: hoặc vẫn giữ trạng thái q1 và Push vào Stack nếu xem ký hiệu này vẫn thuộc chuỗi xuôi (w), hoặc chuyển sang trạng thái q2 và Pop khỏi Stack nếu xem nó là ký hiệu bắt đầu cho chuỗi ngược (wR).

Mô tả PDA không đơn định chấp nhận ngôn ngữ {wwR |w ∈ (0+1)*} bằng Stack rỗng

M ({q1, q2}, {0, 1}, {R, B, Y}, d, q1, R, ∅ size 12{ emptyset } {} )

1) d(q1, 0, R) = {(q1, BR)}

2) d(q1, 1, R) = {(q1,YR)}

3) d(q1, 0, B) = {(q1, BB), (q2, e)}

4) d(q1, 0, Y) = {(q1, BY)}

5) d(q1, 1, B) = {(q1, YB)}

6) d(q1, 1, Y) = {(q1, YY),(q2, e)}

7) d(q2, 0, B) = {(q2, e)}

8) d(q2, 1, Y) = {(q2, e)}

9) d(q1, e, R) = {(q2, e)}

10) d(q2, e, R) = {(q2, e)}

Hình 6.4 - Mô tả PDA không đơn định chấp nhận wwR bằng Stack rỗng

Quy tắc (1) đến (3) cho phép M lưu trữ input trên Stack, quy tắc (3) và (6) cho phép M lựa chọn một trong hai phép chuyển. M có thể quyết định (đoán) đã đi đến giữa chuỗi nó chuyển sang phép chuyển thứ 2: M chuyển sang q2 và thử sự thích hợp của phần chuỗi còn lại với các ký hiệu đang ở trên Stack. Nếu M đoán đúng và nếu chuỗi nhập có dạng wwR thì M sẽ làm rỗng Stack của nó và chấp nhận chuỗi nhập.

Cũng như NFA một PDA không đơn định (NPDA) M chấp nhận một input nếu có một chuỗi các lựa chọn mà M làm rỗng Stack của nó. Nghĩa là M luôn luôn "đoán đúng", đoán sai không phải là nguyên nhân để loại bỏ input. Một input bị loại bỏ nếu và chỉ nếu không có sự lựa chọn nào để làm rỗng Stack (hay là không thể "đoán đúng" vì không tồn tại cách đúng).

Thí dụ 6.4 : Các phép chuyển hình thái của PDA chấp nhận chuỗi 001100 thuộc ngôn ngữ {wwR | w ∈ (0+1)*} bằng Stack rỗng như sau :

Khởi đầu

¯

(q1, 001100, R) ® (q2, 001100, e) : Không chấp nhận

¯

(q1, 01100, BR) ® (q2, 1100, R) ® (q2, 1100, e) : Không chấp nhận

¯

(q1, 1100, BBR)

¯

(q1, 100, YBBR) ® (q2, 00, BBR)

¯ ¯

(q1, 00, YYBBR) (q2, 0, BR) → (q2, e, R) → (q2, e, e) : Chấp nhận

¯

(q1, 0, BYYBBR) ® (q2, e, YYBBR) : Không chấp nhận

¯

(q1, e, BBYYBBR) : Không chấp nhận

Hình 6.5 - Hình thái của PDA với input 001100

PDA đơn định (DPDA)

Một PDA M (Q, Σ, Γ, δ, q0, Z0, F) được gọi là đơn định nếu:

1) ∀q ∈ Q và Z ∈ Γ: nếu δ(q, ε, Z) ≠ ∅ size 12{ emptyset } {} thì δ(q, a, Z) = ∅ size 12{ emptyset } {}, ∀a ∈ Σ

2) Không có q ∈Q, Z ∈ Γ và a ∈ (Σ  {ε}) mà δ(q, a, Z) chứa nhiều hơn một phần tử.

Điều kiện 1 không cho phép khả năng chọn lựa giữa phép chuyển không xác định ký hiệu nhập (ε - dịch chuyển) và phép chuyển trên một ký hiệu input. Điều kiện 2 không cho phép chọn lựa một vài phép chuyển nào đó (q, a, Z) hay (q, ε, Z). Không như ôtômát hữu hạn FA, một PDA thì thông thường được xét là không đơn định trừ khi ta có ghi chú cụ thể.

Đối với ôtômát hữu hạn, dạng đơn định và không đơn định là tương đương nhau về phương diện chấp nhận ngôn ngữ. Tuy nhiên, điều này không đúng với ôtômát đẩy xuống, PDA không đơn định và PDA đơn định là không tương đương nhau. Thực tế ngôn ngữ wwR được chấp nhận bởi một PDA không đơn định nhưng không được chấp nhận bởi bất kỳ một PDA đơn định nào.

0