Логика предикатов в Haskell
Я использую следующую структуру данных для представления логики предложений в Haskell:
data Prop
= Pred String
| Not Prop
| And Prop Prop
| Or Prop Prop
| Impl Prop Prop
| Equiv Prop Prop
deriving (Eq, Ord)
любые комментарии по этой структуре приветствуются.
однако теперь я хочу расширить свои алгоритмы для обработки логики fol-предикатов. Что было бы хорошим способом представить FOL в Haskell?
Я видел версии, которые являются - в значительной степени-расширением вышеизложенного, и версии, основанные на более классических контекстно-свободных грамматиках. Есть есть какая-нибудь литература по этому поводу, которую можно было бы рекомендовать?
2 ответов
это называется абстрактный синтаксис высшего порядка.
первый вариант: используйте лямбду Хаскелла. Тип данных может выглядеть так:
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))))
это подробно описано в in Читатель Монады статьи. Настоятельно рекомендуемый.
второй вариант:
использовать строки типа
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"))))))
преимущество в том, что вы можете легко показать формулу (трудно показать
кажется уместным добавить ответ здесь, чтобы упомянуть функциональную жемчужину используя круговые программы для высших синтаксис, Аксельссон и Классен, который был представлен на ICFP 2013, и кратко описывается Чюиусано на своем блоге.
Это решение аккуратно сочетает в себе аккуратное использование синтаксиса Haskell (первое решение@sdcvvc) с возможностью легко печатать формулы (второе решение@sdcvvc).
forAll :: (Prop -> Prop) -> Prop
forAll f = ForAll n body
where body = f (Var n)
n = maxBV body + 1
bot :: Name
bot = 0
-- Computes the maximum bound variable in the given expression
maxBV :: Prop -> Name
maxBV (Var _ ) = bot
maxBV (App f a) = maxBV f `max` maxBV a
maxBV (Lam n _) = n
Это решение будет использовать тип данных, такой как:
data Prop
= Pred String [Name]
| Not Prop
| And Prop Prop
| Or Prop Prop
| Impl Prop Prop
| Equiv Prop Prop
| ForAll Name Prop
deriving (Eq, Ord)
но позволяет писать формулы в виде:
forAll (\x -> Pred "P" [x] `Impl` Pred "Q" [x])