Thuật toán để quyết định tính tương đương alpha của các thuật ngữ trong các ngôn ngữ có ràng buộc


7

Tôi quan tâm đến mối quan hệ tương đương alpha trong các ngôn ngữ có các ràng buộc thay đổi, chẳng hạn như:

t := x:y    'x belong to y'
  | bot     'False'
  | t -> t  'implication'
  | Ax.t    'forall x, t'

Hoặc phép tính lambda thuần túy:

t := x       'variable'
  | (t t)    'application '
  | Lx.t     'abstraction: \x -> t'

Tôi đang tìm kiếm một thuật toán cho phép tôi xác định xem hai thuật ngữ của ngôn ngữ có tương đương với alpha hay không. Bất kỳ tài liệu tham khảo được công bố là rất hoan nghênh. Tôi giả sử biểu diễn dữ liệu của các thuật ngữ dưới dạng loại đệ quy tiêu chuẩn, ví dụ như trong Haskell:

newtype Var = Var Int 
data Term = Belong Var Var
          | Bot
          | Imply Term Term
          | Forall Var Term 

Câu trả lời:


9

Có một số cách để làm những gì bạn muốn. Một trong số đó là sử dụng một biểu diễn cú pháp khác theo đó thuật ngữ tương đương thực sự bằng nhau. Các đại diện như vậy đi theo cú pháp không tên hoặc địa phương không tên . Một phổ biến sử dụng các chỉ số de Bruijn . Xem các bài đăng trên blog của tôi Cách thực hiện lý thuyết loại phụ thuộc I , IIIII để có phần giới thiệu tuyệt vời để thực hiện loại điều này (phần III đã giải thích các chỉ số de Bruijn).α

Nếu bạn nhấn mạnh vào đại diện của bạn, thì chúng tôi vẫn có thể bí mật sử dụng các chỉ số de Bruijn, như sau. Khi chúng tôi đi xuống bên trong một subterm trong khi so sánh, chúng tôi giữ một danh sách các cặp biến bị ràng buộc cho đến nay gặp phải. Ví dụ, khi so sánh Forall x1 e1Forall x2 e2, chúng tôi thêm cặp (x1, x2)vào danh sách và so sánh đệ quy e1e2. Khi được yêu cầu so sánh các biến xy, chúng tôi tìm kiếm danh sách: cả hai đều phải xuất hiện ở cùng một điểm (chúng bị ràng buộc bởi cùng một bộ định lượng) hoặc không xuất hiện và chúng bằng nhau (cả hai đều miễn phí và chúng bằng nhau).

Tôi không rành về Haskell, nhưng bạn sẽ nhận được một cái gì đó như thế này:

newtype Var = Var Int deriving Eq

data Term = Belong Var Var
          | Bot
          | Imply Term Term
          | Forall Var Term

equalVar :: [(Var,Var)] -> Var -> Var -> Bool
equalVar [] x y = (x == y)
equalVar ((x,y):bound) z w = (x == z && y == w) || (x /= z && y /= w && equalVar bound z w)

equal' :: [(Var, Var)] -> Term -> Term -> Bool
equal' bound (Belong x1 y1) (Belong x2 y2) = (equalVar bound x1 x2 && equalVar bound y1 y2)
equal' bound Bot Bot = True
equal' bound (Imply u1 v1) (Imply u2 v2) = equal' bound u1 u2 && equal' bound v1 v2
equal' bound (Forall x u) (Forall y v) = equal' ((x,y):bound) u v
equal' _ _ _ = False

equal :: Term -> Term -> Bool
equal e1 e2 = equal' [] e1 e2

Andrej, điều này hoạt động hoàn hảo cảm ơn bạn!
Sven Williamson
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.