Это называется higher-order abstract syntax.
Первое решение: Использование лямбда Haskell. Тип данных может выглядеть следующим образом:
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)
Вы можете написать формулу:
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 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
). Недостатком является то, что вы должны писать изменения имен при столкновении (~ альфа-преобразование) и подстановке (~ бета-преобразование). В обоих решениях, вы можете использовать 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. Это называется цифрами Брюйна. См. I am not a number - I am a free variable.
Я думаю, у меня есть некоторое чтение делать .. спасибо! Я вернусь сюда после того, как закончу статьи. – wen
Просто nitpicking, но это все еще альфа-конверсия, даже если это происходит во время замещения. – finrod
Я считаю, что термин «синтаксис высших порядков» применяется только к первому решению. Ваш ответ кажется, что сама проблема (или все три решения) известна как HOAS. –