バインディングを持つ言語で用語のアルファ同等性を決定するためのアルゴリズム


7

次のような変数バインディングを使用する言語のアルファ同値関係に興味があります。

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

または純粋なラムダ計算:

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

言語の2つの用語がアルファ相当であるかどうかを判断できるアルゴリズムを探しています。公開されたリファレンスも大歓迎です。私は、Haskellのように、標準的な再帰型として用語のデータ表現を想定しています。

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

回答:


9

やりたいことを行うにはいくつかの方法があります。それらの1つは、異なる構文表現を使用することです。α-同等の用語は実際には等しいです。このような表現は、名前のない、またはローカルで名前のない構文という名前で行われます。人気のあるものは、de Bruijnインデックスを使用しています。この種のことを実装するための電撃的な導入については、私のブログの投稿「依存型理論を実装する方法IIIIII 」を参照してください(パートIIIでde Bruijnインデックスが説明されています)。

あなたがあなたの表現を主張するならば、それでも私達は次のようにド・ブルイン指標を密かに使用するかもしれません。比較中にサブターム内を下降するとき、これまでに遭遇したバインドされた変数のペアのリストを保持します。たとえば、Forall x1 e1and Forall x2 e2を比較する場合、ペア(x1, x2)をリストに追加し、再帰的にe1andを比較しe2ます。変数xとを比較するように求められたらy、リストを検索します。どちらも同じスポットに表示される必要があります(同じ数量詞によってバインドされていました)か、どちらも表示されておらず、等しい(どちらも自由であり、等しい)かのいずれかです。

私はHaskellに精通していませんが、次のようなものが得られます。

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

アンドレジ、これは完璧に機能します。ありがとうございます。
Sven Williamson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.