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 , II và III để 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 e1
và Forall x2 e2
, chúng tôi thêm cặp (x1, x2)
vào danh sách và so sánh đệ quy e1
và e2
. Khi được yêu cầu so sánh các biến x
và y
, 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