Логика предикатов в 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])