Sự khác biệt giữa viết lại thuật ngữ và khớp mẫu là gì?


25

không có phản hồi tại Lambda, Ultimate tôi thử lại ở đây: các hệ thống viết lại thuật ngữ được sử dụng ví dụ trong định lý tự động chứng minh một phép tính tượng trưng, ​​và tất nhiên để xác định ngữ pháp chính thức. Có một số ngôn ngữ lập trình dựa trên thuật ngữ viết lại, nhưng theo tôi hiểu khái niệm này được gọi là khớp mẫu . Khớp mẫu được sử dụng rất nhiều trong các ngôn ngữ chức năng. Barry Jay đã tạo ra một lý thuyết toàn bộ được gọi là phép tính mẫu , nhưng ông chỉ đề cập đến việc viết lại thuật ngữ một cách ngắn gọn. Tôi có cảm giác rằng tất cả chúng đều đề cập đến cùng một ý tưởng cơ bản, vì vậy bạn có thể sử dụng thuật ngữ viết lạikhớp mẫu đồng nghĩa không?

Câu trả lời:


26

Một cách để xem xét hai khái niệm này là nói rằng khớp mẫu là một tính năng của ngôn ngữ lập trình để kết hợp phân biệt đối xử trên các hàm tạo và các thuật ngữ phá hủy (đồng thời chọn và đặt tên các đoạn thuật ngữ cục bộ) một cách an toàn, gọn gàng và hiệu quả. Nghiên cứu về khớp mẫu thường tập trung vào hiệu quả thực hiện, ví dụ về cách giảm thiểu số lượng so sánh mà cơ chế khớp phải thực hiện.

Ngược lại, viết lại thuật ngữ là một mô hình tính toán tổng quát , nghiên cứu một loạt các phương pháp (có khả năng không xác định) thay thế các tập hợp con của biểu thức cú pháp (chính xác hơn là một yếu tố của thuật ngữ đại số trên một số biến) bằng các thuật ngữ khác. Nghiên cứu về các hệ thống viết lại thuật ngữ thường là về các thuộc tính trừu tượng của các hệ thống viết lại như hợp lưu, xác định và chấm dứt, và cụ thể hơn là làm thế nào các tính chất đó được hoặc không được bảo tồn bởi các hoạt động đại số trên các hệ thống viết lại, nghĩa là các thuộc tính này được cấu tạo ở mức độ nào.

Rõ ràng có sự chồng chéo về mặt khái niệm giữa cả hai, và sự khác biệt là ở một mức độ truyền thống, chứ không phải là kỹ thuật. Một sự khác biệt về kỹ thuật là việc viết lại thuật ngữ xảy ra trong các bối cảnh tùy ý (nghĩa là một quy tắc gây ra việc viết lại cho các bối cảnh tùy ý Và thay thế ), trong khi khớp mẫu trong các ngôn ngữ hiện đại như Haskell, OCaml hoặc Scala chỉ cung cấp cho việc viết lại 'ở đầu' của một thuật ngữ. Hạn chế này cũng là, tôi nghĩ, áp đặt trong tính toán mô hình của Jay. Hãy để tôi giải thích những gì tôi có nghĩa là hạn chế này. Với kết hợp mẫu theo nghĩa OCaml, Haskell, Scala, bạn không thể nói điều gì đó như(tôi,r)C[tôiσ]C[rσ]C[.]σ

match M with
   | C[ x :: _ ]  -> printf "%i ...\n" x
   | C[ [] ] -> printf "[]"

Cái gì C[.]đây Nó được coi là một biến nằm trong bối cảnh một chiều. Nhưng các ngôn ngữ như OCaml, Haskell hoặc Scala không cung cấp cho các lập trình viên các biến trong phạm vi bối cảnh tùy ý (một chiều), chỉ các biến nằm trong phạm vi giá trị. Nói cách khác, trong các ngôn ngữ như vậy, bạn không thể tạo mẫu khớp ở vị trí tùy ý trong một thuật ngữ. Bạn luôn phải chỉ định đường dẫn từ gốc của mẫu đến các phần mà bạn quan tâm. Tôi đoán lý do chính để áp đặt hạn chế này là nếu không thì khớp mẫu sẽ không xác định, vì thuật ngữ có thể khớp với mẫu trong nhiều hơn một cách Ví dụ: thuật ngữ (true, [9,7,4], "hello", 7)khớp với mẫu C[7]theo hai cách, giả sử C[.] nằm trong các bối cảnh như vậy.


11

Tôi không nghĩ nó đúng khi gọi chúng là từ đồng nghĩa; có một số sự chồng chéo về mặt nghiên cứu và thực hiện. Tôi hoàn toàn không quen thuộc với công việc của Jay và tôi chỉ hơi quen thuộc với các hệ thống viết lại thuật ngữ, vì vậy tôi cũng có thể thiếu một cái gì đó.

Khớp mẫu trong các vấn đề chung liên quan đến vấn đề sau: bạn có một số cấu trúc (cây hoặc danh sách hoặc nhiều trang) và bạn muốn kiểm tra xem cấu trúc đó có khớp với một mẫu (hoặc một trong một số mẫu) không. Câu hỏi này chắc chắn có liên quan đến việc viết lại thuật ngữ, bởi vì trong các hệ thống viết lại thuật ngữ, thực tế là một thuật ngữ phù hợp với một mẫu có nghĩa là thuật ngữ này có thể được viết lại thành một thuật ngữ khác, nhưng nó không đồng nghĩa với việc viết lại thuật ngữ. (Có thể có một công thức khớp mẫu như viết lại: "Đưa ra một thuật ngữ, bạn có thể viết lại nó cho phù hợp với mẫu không?" Nhưng tôi chưa bao giờ thấy điều này.)

Kết hợp mẫu trong ngôn ngữ lập trình chức năng có một cách giải thích hợp lý về mặt tập trung ( ví dụ: xem "Tập trung vào khớp mẫu" của Krishnaswami ). Mặt khác, các hệ thống viết lại thuật ngữ thường khớp với modulo một số thuộc tính tương đương, không có trong hầu hết các ngôn ngữ lập trình chức năng (bạn không thể so sánh với nhiều trang trong ML hoặc Haskell). Tuy nhiên, không có lý do cơ bản tại sao khớp các thuộc tính phương trình modulo không nên có trong các ngôn ngữ chức năng.


1
Cảm ơn câu trả lời của bạn. Tôi đồng ý rằng khớp mẫu nói chung không đồng nghĩa với viết lại thuật ngữ nhưng nó cơ bản hơn. Nhưng nếu ai đó nói rằng một hệ thống có sức mạnh tính toán dựa trên khớp mẫu, tôi không thể thấy sự khác biệt so với hệ thống viết lại thuật ngữ có sức mạnh tính toán. Bạn có thể nêu rõ hơn về sự khác biệt giữa "có một cách hiểu logic" và "một số tính chất tương đương" không?
Jakob

"Tôi không thể thấy sự khác biệt của một hệ thống viết lại thuật ngữ với sức mạnh tính toán" - Tôi không chắc điều này có nghĩa là gì. Như Martin nói, viết lại thuật ngữ là một mô hình tính toán chung và khớp mẫu là một tính năng, không phải là mô hình tính toán.
Rob Simmons

Bạn có thể nêu rõ hơn về sự khác biệt giữa "có một cách hiểu logic" và "một số tính chất tương đương" không? - Không có bất kỳ sự khác biệt nông nào - chúng chỉ là những tính chất, táo và cam khác nhau. Tôi nghĩ rằng bất kỳ kết nối thực tế giữa hai người này có thể trở thành một câu hỏi nghiên cứu khá sâu sắc! Pun với suy luận sâu sắc - xem alessio.guglielmi.name/res/cos - có thể dự định.
Rob Simmons

1

(Tôi muốn viết điều này như một bình luận, nhưng hiện tại tôi không thể.)

Sửa lỗi cho tôi nếu tôi sai, nhưng theo tôi hiểu, một điểm khác biệt nữa giữa khớp mẫu và viết lại thuật ngữ, ngoài những gì Martin Berger đã nói trong câu trả lời xuất sắc của mình , đó là các quy tắc khớp mẫu đi kèm theo một trật tự cố định (trong các triển khai như Haskell's), trong khi với các quy tắc viết lại thuật ngữ, điều này không nhất thiết phải như vậy. Tính năng này, như người ta mong đợi, có thể tạo ra nhiều sự khác biệt khi xem xét hành vi (cụ thể là chấm dứt) các quy tắc (xem "Giới thiệu nhẹ nhàng về Haskell, Phiên bản 98", ví dụ, phần 4.2 , hoặc chỉ là yếu tố ví dụ tại "Tìm hiểu bạn một Haskell" ).

Mọi người hiểu biết nhiều hơn về lý thuyết viết lại sẽ có nhiều điều để nói hơn về điều đó (ví dụ, làm thế nào để gõ phù hợp chính xác như vậy?), Nhưng, có vẻ như tôi công bằng khi đồng ý với Martin Berger, trong đó thuật ngữ viết lại có thể được nhìn thấy để bao quát khớp mẫu (ít nhất là điều này được triển khai bằng các ngôn ngữ như Haskell), đến mức cả hai có thể (khá khô khan) được xem là thiết bị chỉ sử dụng các quy tắc liên quan đến thuật ngữ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.