Tóm lại
Không biết đủ tài liệu, tôi đã tìm ra một giải pháp được trình bày trong phần tiếp theo, cùng với một bằng chứng cho phần khó nhất. Một khi tôi biết những gì cần thiết, tôi có thể tìm kiếm tài liệu cho những ý tưởng phù hợp. Dưới đây là một bản trình bày nhanh về thuật toán, dựa trên tài liệu, về cơ bản giống như tôi đã phát triển.
Điều đầu tiên cần làm là tìm một chuỗi thiết bị đầu cuối có kích thước tối thiểu
cho mọi không đầu cuối của ngữ pháp. Điều này có thể được thực hiện bằng cách sử dụng phần mở rộng của Knuth cho conc-hoặc đồ thị (còn được gọi là ngữ pháp CF) và và hoặc đồ thị của thuật toán đường đi ngắn nhất của Dijkstra . Ví dụ B trong bài báo của Knuth làm những gì cần thiết, gần như.σ(U)U
Trên thực tế, Knuth chỉ tính toán độ dài của các chuỗi đầu cuối này, nhưng khá dễ dàng để sửa đổi thuật toán của anh ta để thực sự tính toán một chuỗi đầu cuối như vậy cho mỗi không đầu cuối (như tôi làm trong phiên bản của mình bên dưới) . Chúng tôi cũng định nghĩa cho mọi thiết bị đầu cuối và chúng tôi mở rộng như bình thường thành một phép đồng hình chuỗi.σ(U)Uσ(a)=aaσ
Sau đó, chúng tôi xem xét một biểu đồ có hướng trong đó các thiết bị đầu cuối không phải là các nút và có một cung nếu có quy tắc . Nếu một số quy tắc như vậy có thể tạo ra cùng một cung , chúng ta sẽ giữ một cung sao cho độ dàilà tối thiểu Vòng cung được gắn nhãn theo quy tắc đó và độ dài tối thiểu đó
trở thành trọng lượng của vòng cung.(U,V)U→αVβ(U,V)|σ(αβ)||σ(αβ)|
Cuối cùng, bằng cách sử dụng thuật toán đường dẫn ngắn nhất của Dijkstra, chúng tôi tính toán đường đi ngắn nhất từ không đầu cuối ban đầu đến từng đầu cuối của ngữ pháp. Đưa ra đường dẫn ngắn nhất cho không đầu cuối , các nhãn quy tắc trên các cung có thể được sử dụng để lấy đạo hàm
. Sau đó, theo mọi quy tắc của mẫu trong ngữ pháp, chúng tôi liên kết chuỗi thiết bị đầu cuối kích thước tối thiểu có thể được bắt nguồn bằng quy tắc đó.SUS⟹∗αUβU→γσ(αγβ)
Để đạt được độ phức tạp thấp , cả thuật toán của Dijkstra và phần mở rộng của Knuth đều được triển khai với hàng đống , hàng đợi ưu tiên AKA. Điều này mang lại cho thuật toán của Dijkstra độ phức tạp của và đối với thuật toán của Knuth, độ phức tạp , trong đó có
quy tắc ngữ pháp và không phải là thiết bị đầu cuối và là tổng chiều dài của tất cả các quy tắc. Toàn bộ bị chi phối bởi sự phức tạp của thuật toán Knuth kể từ .O(nlogn+t)O(mlogn+t)mntm≥n
Những gì tiếp theo là công việc của riêng tôi, trước khi tôi đưa ra câu trả lời ngắn gọn ở trên.
Xuất phát giải pháp từ thuật toán loại bỏ biểu tượng vô dụng.
Có một số khía cạnh của thuật toán này. Để có trực giác tốt hơn, tôi đã chọn trình bày nó trong ba phiên bản liên tiếp giới thiệu nhiều tính năng hơn. Phiên bản đầu tiên không trả lời câu hỏi, nhưng là một thuật toán tiêu chuẩn để loại bỏ các biểu tượng vô dụng gợi ý một giải pháp. Phiên bản thứ hai trả lời câu hỏi mà không có ràng buộc tối thiểu, Phiên bản thứ ba đưa ra câu trả lời cho câu hỏi, thỏa mãn ràng buộc tối thiểu của bạn. Giải pháp thứ ba này sau đó được cải thiện bằng cách sử dụng một sự thích ứng với và hoặc đồ thị của thuật toán đường đi ngắn nhất của Dijkstra .
Kết quả cuối cùng là một thuật toán rất đơn giản, tránh việc xem xét lại các tính toán đã được thực hiện. Nhưng nó ít trực quan hơn và không cần bằng chứng.
Câu trả lời này chỉ cố gắng trả lời câu hỏi được đưa ra chính xác theo nhận xét của OP: " với mỗi quy tắc sản xuất, tôi muốn tạo một chuỗi tối thiểu đưa trình phân tích cú pháp từ trạng thái bắt đầu, thông qua quá trình sản xuất được kiểm tra, đến một bộ thiết bị đầu cuối. "Do đó, tôi chỉ cố gắng lấy một chuỗi các chuỗi sao cho mỗi quy tắc, có một chuỗi trong tập hợp đó là một trong các chuỗi tối thiểu kích thước của ngôn ngữ có đạo hàm sử dụng quy tắc.
Tuy nhiên, cần lưu ý rằng thực tế là một chuỗi "gọi" một quy tắc, có nguồn gốc bằng quy tắc đó, không nhất thiết có nghĩa là quy tắc này sẽ được xem xét bởi một trình phân tích cú pháp làm việc với các ngữ pháp mơ hồ và giải quyết sự mơ hồ một cách tùy tiện. Xử lý một tình huống như vậy có lẽ sẽ đòi hỏi kiến thức chính xác hơn về trình phân tích cú pháp và có thể là một câu hỏi phức tạp hơn.
Thuật toán cơ bản
Để giải quyết câu hỏi này, người ta có thể bắt đầu với thuật toán cổ điển để loại bỏ các ký hiệu vô dụng trong ngữ pháp không ngữ cảnh. Nó nằm trong phần 4.4, trang 88-89, của Hopcroft & Ullman, phiên bản 1979. Nhưng cách trình bày ở đây có thể hơi khác một chút.
Thuật toán nhằm mục đích chính xác là chứng minh sự tồn tại của lớp phủ như vậy theo yêu cầu của OP và bao gồm hai phần:
bổ đề 4.1 của H & U, trang 88: loại bỏ tất cả các thiết bị đầu cuối không hiệu quả . Điều này được thực hiện bằng cách thử tìm cho mỗi thiết bị đầu cuối một chuỗi thiết bị đầu cuối mà nó có thể xuất phát. Một cách đơn giản để giải thích nó như sau: Bạn tạo một biểu tượng sản xuất od, mà bạn khởi tạo với tất cả các thiết bị đầu cuối. Sau đó, đối với mỗi quy tắc, chưa được xử lý, có tất cả các ký hiệu bên phải (RHS) trong , bạn thêm thiết bị đầu cuối bên trái (LHS) vào đã đặt và bạn xóa tất cả quy tắc bằng cùng một thiết bị đầu cuối LHS từ bộ quy tắc sẽ được xử lý. Bạn lặp lại quy trình cho đến khi không còn quy tắc nào với tất cả các biểu tượng RHS của nó trong . Các thiết bị đầu cuối còn lại, không có trongProdProdProdProdProdở cuối quá trình này, là không có năng suất: chúng không thể được dẫn xuất thành một chuỗi đầu cuối và do đó có thể được loại bỏ khỏi ngữ pháp.
bổ đề 4.2 của H & U, trang 89: loại bỏ tất cả các biểu tượng không thể truy cập . Điều này được thực hiện bởi khả năng tiếp cận nút cổ điển trong các đồ thị có hướng, bằng cách coi các thiết bị đầu cuối không phải là nút và có một cung nếu có một quy tắc sao cho
xảy ra trong . Bạn có thể tạo một tập các biểu tượng có thể truy cập được khởi tạo với chỉ biểu tượng ban đầu . Sau đó, với mọi ký hiệu không đầu cuối trong hoặc sau đó được thêm vào nó và với mọi quy tắc , bạn thêm vào tất cả các ký hiệu trong(U,V)U→αVαReachSUReachU→αReachα. Do đó, khi tất cả các thiết bị đầu cuối trong đã được xử lý, tất cả các ký hiệu (thiết bị đầu cuối hoặc không phải thiết bị đầu cuối) không có trong không thể xuất hiện trong một chuỗi có nguồn gốc từ biểu tượng ban đầu và do đó vô dụng. Vì vậy, chúng có thể được loại bỏ khỏi ngữ pháp.ReachReach
Hai thuật toán cơ bản này rất hữu ích để đơn giản hóa kết quả thô của một số kỹ thuật xây dựng ngữ pháp, chẳng hạn như được sử dụng cho giao điểm của ngôn ngữ không ngữ cảnh và bộ thông thường. Đặc biệt, điều này rất hữu ích trong việc làm sạch kết quả của các trình phân tích cú pháp CF chung .
Loại bỏ các ký hiệu không đầu cuối vô dụng là cần thiết trong bối cảnh giải quyết câu hỏi được hỏi, vì các quy tắc sử dụng chúng không thể được gọi ra (nghĩa là được sử dụng trong dẫn xuất của nó) bởi bất kỳ chuỗi ngôn ngữ nào.
Xây dựng một chuỗi các chuỗi gọi mọi quy tắc
(Chúng tôi chưa tìm kiếm các chuỗi tối thiểu.)
Bây giờ trả lời cụ thể câu hỏi, người ta thực sự phải loại bỏ tất cả các biểu tượng vô dụng, cho dù các biểu tượng không thể truy cập hoặc các biểu tượng không đầu cuối không hiệu quả, một quy tắc vô dụng cũng có các thiết bị đầu cuối vô dụng như LHS. Chúng không có cơ hội được gọi một cách hữu ích khi phân tích chuỗi thiết bị đầu cuối (mặc dù một số có thể lãng phí thời gian xử lý của trình phân tích cú pháp khi chúng không bị xóa; cái nào có thể lãng phí thời gian phụ thuộc vào công nghệ trình phân tích cú pháp).
Bây giờ chúng tôi xem xét, đối với mỗi quy tắc (hữu ích), việc sản xuất một chuỗi đầu cuối gọi nó, tức là có thể được tạo bằng cách sử dụng quy tắc này. Đây thực chất là những gì được thực hiện bởi hai thuật toán trên, mặc dù chúng không lưu giữ thông tin, vì chúng hài lòng với việc chứng minh sự tồn tại của các chuỗi này để đảm bảo rằng các thiết bị đầu cuối không thể truy cập và có hiệu quả.
Chúng tôi sửa đổi thuật toán đầu tiên (bổ đề 4.1) bằng cách giữ với mỗi không đầu cuối trong tập một chuỗi đầu cuối mà nó xuất phát trên: . Đối với mỗi thiết bị đầu cuối, chúng tôi xác định là ánh xạ định danh. Khi được thêm vào tập vì quy tắc
có tất cả các ký hiệu RHS của nó trong , sau đó chúng tôi xác định
, mở rộng dưới dạng đồng cấu trên chuỗi và chúng tôi loại bỏ tất cả các , đó là tất cả các quy tắc với là LHS.UProdσ(U)U⟹∗σ(U)σUProdU→γProdσ(U)=σ(γ)σUU
Chúng tôi sửa đổi thuật toán thứ hai (bổ đề 4.2) bằng cách giữ với mỗi ký hiệu không đầu cuối được thêm vào đường dẫn được sử dụng để tiếp cận nó từ ký hiệu intial , đưa ra các quy tắc liên tiếp để lấy đạo hàm .UReachSS⟹∗αUβ
Sau đó, với mỗi quy tắc trong ngữ pháp, chúng tôi tạo ra một chuỗi đầu cuối "gọi" quy tắc này như sau. Chúng tôi lấy từ kết quả của thuật toán thứ hai, đạo hàm
. Sau đó, chúng tôi áp dụng quy tắc để có được chuỗi . Chuỗi đầu cuối "gọi" quy tắc làU→γS⟹∗αUβαγβU→γσ(αγβ)
Xây dựng một chuỗi các chuỗi tối thiểu "gọi" mọi quy tắc
Chúng tôi bỏ qua vấn đề loại bỏ các biểu tượng vô dụng, có thể là sản phẩm phụ của các thuật toán được sửa đổi này.
Việc xây dựng một tập hợp các chuỗi tối thiểu phụ thuộc vào việc đầu tiên nhận được một chuỗi dẫn xuất tối thiểu cho mỗi thiết bị đầu cuối. Điều này được thực hiện bằng cách sửa đổi thêm thuật toán đầu tiên (bổ đề 4.1). Trước tiên, chúng tôi xóa khỏi bộ quy tắc để được xử lý tất cả các quy tắc đệ quy (nghĩa là có ký hiệu LHS xảy ra trong chuỗi RHS). Rõ ràng là không có quy tắc nào trong số các quy tắc này có thể xuất phát từ một chuỗi thiết bị đầu cuối ngắn hơn các quy tắc không đệ quy có cùng LHS. Và phải có ít nhất một quy tắc không đệ quy nếu LHS không phải là một thiết bị đầu cuối vô dụng (vì không sản xuất).
Sau đó, chúng tôi xử lý như trước để xây dựng của các ký hiệu sản xuất, liên kết với mỗi synbol một chuỗi đầu cuối, mà chúng tôi lưu ý . Chuỗi được tạo ra như trước bằng cách áp dụng quy tắc , thay thế từng không đầu cuối xảy ra trong bằng . Cho đến nay, chỉ cần áp dụng quy tắc này cho một quy tắc với một không đầu cuối nhất định
là LHS của nó, đầu tiên sẽ có tất cả các đầu cuối RHS không có đầu cuối trong
ProdUσ(U)σ(U)U→γVγσ(V)UProdvà sau đó bỏ qua những cái khác, bởi vì bất kỳ chuỗi dẫn xuất nào như vậy sẽ làm. Nhưng chúng tôi đang tìm kiếm một chuỗi dẫn xuất tối thiểu. Do đó, đối với không đầu cuối , điều này phải được thực hiện cho tất cả các quy tắc với là LHS. Nhưng chúng tôi chỉ giữ một chuỗi thiết bị đầu cuối , thay thế chuỗi hiện tại bằng chuỗi mới được tìm thấy, bất cứ khi nào chuỗi mới nhỏ hơn.UUσ(U)
Hơn nữa, bất cứ khi nào chuỗi được thay thế bằng một chuỗi nhỏ hơn, tất cả các quy tắc có sự xuất hiện của trong RHS đã được xử lý phải được đặt lại trong bộ quy tắc cần xử lý, vì thay đổi cho phép xuất phát RHS của họ trên một chuỗi ngắn hơn. Vì vậy, làm điều này sẽ đòi hỏi nhiều lần lặp hơn, nhưng cuối cùng sẽ kết thúc vì không có chuỗi nào trong số các chuỗi này ngắn hơn nhiều so với chuỗi trống.σ(U)U
Vào cuối của thuật toán đầu tiên này, chuỗi là một trong những chuỗi nhỏ nhất có thể được bắt nguồn từ . Có thể có người khác.σ(U)U
Bây giờ chúng ta cũng phải sửa đổi thuật toán thứ hai để có được, với mọi không đầu cuối , (một trong) chuỗi ngắn nhất chứa U là duy nhất không đầu cuối. Để làm điều này, chúng tôi giữ cùng một đồ thị có hướng với các nút không phải là các nút và có một cung nếu có quy tắc
. Nhưng bây giờ chúng tôi đặt trọng số lên các cung, để tính độ dài tối thiểu của bối cảnh thiết bị đầu cuối phải được liên kết với các thiết bị đầu cuối không tiếp cận được. Trọng số liên quan đến cung ở trên là chiều dài, nơi ánh xạU(U,V)U→αVβ(U,V)|σ(αβ)|σđược mở rộng đến các thiết bị đầu cuối dưới dạng danh tính, và sau đó được mở rộng lại dưới dạng đồng cấu chuỗi. Đó là độ dài của (một trong) các chuỗi đầu cuối ngắn nhất có thể được lấy từ chuỗi
. Lưu ý rằng được loại bỏ trong tính toán này. HOwever, khi có một vài lần xuất hiện của trong RHS, chỉ một lần phải được loại bỏ. Có thể có một số cung , với các trọng số khác nhau, nếu có một số quy tắc với là LHS và trong RHS. Trong trường hợp như vậy, chỉ (một trong) vòng cung nhẹ hơn như vậy được giữ.αβVV(U,V)UV
Trong biểu đồ này, chúng ta không còn trông giống cho reachability các nút từ
, nhưng đối với con đường ngắn nhất có trọng mà đạt mỗi nút từ biểu tượng ban đầu . Điều này có thể được thực hiện với thuật toán của Dijkstra .SS
Đưa ra con đường ngắn nhất cho một không đầu cuối , chúng ta đọc nó như trước đây như là một chuỗi các quy tắc, từ đó chúng ta nhận được một giới hạn
. Sau đó, theo mọi quy tắc của mẫu trong ngữ pháp, chúng tôi tạo ra một chuỗi thiết bị đầu cuối tối thiểu "gọi" quy tắc này là
US⟹∗αUβU→γσ(αγβ)
Lưu ý : Chuỗi tối thiểu tương tự có thể được sử dụng cho một số quy tắc. Nhưng thực tế là một trong các chuỗi sử dụng quy tắc trong đạo hàm của nó không nhất thiết có nghĩa là một chuỗi tối thiểu cho quy tắc đó , vì nó có thể được tìm thấy cho quy tắc khác, trong khi một chuỗi ngắn hơn có thể được tìm thấy cho . Có thể tăng khả năng rằng chuỗi tối thiểu tương tự sẽ được tìm thấy cho một số quy tắc bằng cách sử dụng một số chính sách ưu tiên bất cứ khi nào có tính linh hoạt. Nhưng nó có đáng để gặp rắc rối không?ρρρ
Một thuật toán nhanh hơn cho chuỗi thiết bị đầu cuối tối thiểu xuất phát từ một thiết bị đầu cuối không
Xây dựng hàm sao cho là một chuỗi đầu cuối tối thiểu xuất phát từ được thực hiện ở trên với một kỹ thuật khá ngây thơ đòi hỏi phải xem xét lại công việc đã được thực hiện khi tìm thấy một chuỗi dẫn xuất nhỏ hơn cho một số đầu cuối không. Điều này là lãng phí, ngay cả khi quá trình sẽ chấm dứt rõ ràng.σσ(U)U
Chúng tôi đề xuất ở đây một thuật toán hiệu quả hơn, về bản chất là sự thích ứng với biểu đồ ngữ pháp CF của một phần mở rộng của thuật toán đường đi ngắn nhất của Dijkstra đến và hoặc đồ thị, với một định nghĩa đúng về khái niệm đường dẫn cho một và hoặc biểu đồ . Biến thể của thuật toán này có thể tồn tại trong tài liệu (giả sử nó là chính xác), nhưng tôi đã không thể tìm thấy nó trong các tài nguyên mà tôi có thể truy cập. Do đó tôi đang mô tả nó chi tiết hơn, cùng với một bằng chứng.
Như trước đây, trước tiên chúng tôi xóa khỏi bộ quy tắc để được xử lý tất cả các quy tắc đệ quy (nghĩa là các quy tắc có ký hiệu LHS xảy ra trong chuỗi RHS). Rõ ràng là không có quy tắc đệ quy nào có thể rút ra chuỗi đầu cuối ngắn hơn quy tắc không đệ quy có cùng LHS. Và, đối với LHS , phải có ít nhất một không đệ quy
nếu ký hiệu không phải là một thiết bị đầu cuối vô dụng (vì không có năng suất). Điều này không thực sự cần thiết, nhưng làm giảm số lượng các quy tắc sẽ được xem xét sau này.UUU
Sau đó, chúng tôi tiến hành xây dựng của các ký hiệu sản xuất, liên kết với mỗi synbol một chuỗi đầu cuối, mà chúng tôi lưu ý , là một chuỗi đầu cuối tối thiểu có kích thước có thể lấy được từ
(trong thuật toán trước đó, chỉ đúng sau khi chấm dứt). Bộ được khởi tạo với tất cả các ký hiệu đầu cuối và với mỗi ký hiệu đầu cuối , chúng tôi xác định .ProdXσ(X)XProdaσ(a)=a
Sau đó, chúng tôi xem xét mọi quy tắc sao cho tất cả các biểu tượng RHS đều có trong và chúng tôi chọn một quy tắc sao cho có kích thước tối thiểu. Sau đó chúng ta thêm để , với , và loại bỏ tất cả -rules. Chúng tôi lặp đi lặp lại cho đến khi tất cả các thiết bị đầu cuối đã được nhập vào . Bất kỳ không đầu cuối nào , một khi đã được nhập vào
, sẽ không bao giờ phải xem xét lại để thay đổi cho một chuỗi nhỏ hơn.U→γProdσ(γ)UProdσ(U)=σ(γ)UProdUProdσ(U)
Bằng chứng :
Các thuật toán trước đây ít nhiều rõ ràng bằng trực giác. Đây là một chút phức tạp hơn, bởi vì và hoặc hoặc nhân vật của biểu đồ, và một bằng chứng dường như cần thiết hơn. Tất cả những gì chúng ta cần thực sự là bổ đề sau, nó thiết lập tính chính xác của thuật toán khi áp dụng cho lần lặp cuối cùng.
Bổ đề : Sau mỗi lần lặp của thuật toán, là một chuỗi đầu cuối kích thước tối thiểu có thể lấy được từ , cho tất cả trong .σ(X)XXProd
Bước cơ bản là rõ ràng, vì điều này là đúng theo định nghĩa cho tất cả các thiết bị đầu cuối trong khi nó được khởi tạo.Prod
Sau đó, giả sử đó là sự thật sau khi một số thiết bị đầu cuối không được thêm vào
, hãy để là quy tắc được chọn để thêm một thiết bị đầu cuối mới vào . Chúng tôi biết rằng quy tắc này được chọn vì
và có kích thước tối thiểu trên tất cả RHS của tất cả các quy tắc có RHS trong . Sau đó sẽ được thêm vào , và chúng tôi chỉ phải chứng minh rằng là một thiết bị đầu cuối chuỗi derivable size-tối thiểu từ .ProdU→γProdγ∈Prod∗σ(γ)Prod∗UProdσ(γ)U
Đây rõ ràng là trường hợp của tất cả các dẫn xuất bắt đầu bằng quy tắc
, vì theo giả thuyết cảm ứng, ứng dụng ánh xạ sao cho tất cả các thiết bị đầu cuối trong được thay thế bằng các chuỗi đầu cuối kích thước tối thiểu xuất phát từ chúng. Do đó không có dẫn xuất khác có thể tạo ra một chuỗi thiết bị đầu cuối ngắn hơn.U→γσσ
Do đó, chúng tôi chỉ xem xét các dẫn xuất bắt đầu bằng một -rule
, sao cho
, trong đó là tập hợp các ký hiệu đầu cuối.UU→ββ⟹∗w∈Σ∗Σ
Nếu , thì một chuỗi tối thiểu mà nó có thể rút ra là
. Nhưng, vì chúng tôi đã chọn quy tắc , nên nó phải là. Vì vậy, quy tắc
không xuất phát từ một chuỗi con thiết bị đầu cuối nhỏ hơn.β∈Prod∗σ(β)U→γ|σ(β)|≥|σ(γ)|U→β
Trường hợp cuối cùng cần xem xét là khi và sau đó chúng tôi xem xét một dẫn xuất . Nếu đạo hàm đó chỉ liên quan đến các số không phải là ba cực trong , thì
, đó là trường hợp chúng ta đã thấy. Do đó, chúng tôi chỉ xem xét các dẫn xuất có các bước sử dụng quy tắc với LHS của nó không có trong . Đặt là một quy tắc, sao cho
. Phải có ít nhất một quy tắc như vậy vì chúng được sắp xếp một phần theo thứ tự phái sinh và .β∉Prod∗β⟹∗w∈Σ∗Prodβ∈Prod∗ProdV→αα∈Prod∗w∈Prod∗
Do đó, chúng ta có . Chúng tôi biết rằng và xuất phát từ một chuỗi có kích thước ít nhất là 0 và vì không có nào có RHS trong được chọn, nên chúng xuất phát từ các chuỗi đầu cuối có độ dài ít nhất bằng
. Do đó, với quy tắc ,
xuất phát trên chuỗi đầu cuối có độ dài ít nhất bằng
. U⟹β⟹∗μVνμνVProd∗|σ(γ)|U→βU|σ(γ)|■