這就是所謂的higher-order abstract syntax。
第一個解決方案:使用Haskell的lambda。 一個數據類型可以是這樣的:
ForAll (\x -> Exists (\y -> Equals (Add x y) (Mul x y))))
對此進行了詳細在The Monad Reader文章描述:
data Prop
= Not Prop
| And Prop Prop
| Or Prop Prop
| Impl Prop Prop
| Equiv Prop Prop
| Equals Obj Obj
| ForAll (Obj -> Prop)
| Exists (Obj -> Prop)
deriving (Eq, Ord)
data Obj
= Num Integer
| Add Obj Obj
| Mul Obj Obj
deriving (Eq, Ord)
,你可以寫一個公式。強烈推薦。
解決方法二:
使用字符串像
data Prop
= Not Prop
| And Prop Prop
| Or Prop Prop
| Impl Prop Prop
| Equiv Prop Prop
| Equals Obj Obj
| ForAll String Prop
| Exists String Prop
deriving (Eq, Ord)
data Obj
= Num Integer
| Var String
| Add Obj Obj
| Mul Obj Obj
deriving (Eq, Ord)
然後,你可以這樣寫
ForAll "x" (Exists "y" (Equals (Add (Var "x") (Var "y")))
(Mul (Var "x") (Var "y"))))))
優勢的公式是,你可以很容易地顯示公式(很難顯示Obj -> Prop
函數)。缺點是您必須在碰撞(〜alpha轉換)和替換(〜beta轉換)時編寫更改的名稱。在兩種方案中,可以使用GADT,而不是兩個數據類型:
data FOL a where
True :: FOL Bool
False :: FOL Bool
Not :: FOL Bool -> FOL Bool
And :: FOL Bool -> FOL Bool -> FOL Bool
...
-- first solution
Exists :: (FOL Integer -> FOL Bool) -> FOL Bool
ForAll :: (FOL Integer -> FOL Bool) -> FOL Bool
-- second solution
Exists :: String -> FOL Bool -> FOL Bool
ForAll :: String -> FOL Bool -> FOL Bool
Var :: String -> FOL Integer
-- operations in the universe
Num :: Integer -> FOL Integer
Add :: FOL Integer -> FOL Integer -> FOL Integer
...
解決方案三:用數字來表示,其中的變量綁定,其中較低的手段更深。例如,在ForAll(Exists(Equals(Num 0)(Num 1)))中,第一個變量將綁定到Exists,第二個綁定到ForAll。這被稱爲de Bruijn數字。見I am not a number - I am a free variable。
我想我有一些閱讀做..謝謝!我在完成文章後會回到這裏。 – wen 2010-07-12 15:27:15
只是挑剔,但它仍然是阿爾法轉換,即使它發生在替代時間。 – finrod 2010-07-12 21:52:10
我認爲術語「高階抽象語法」僅適用於第一種解決方案。你的答案似乎是說問題本身(或所有三種解決方案)被稱爲HOAS。 – 2010-07-12 22:53:35