Haskell中命题逻辑到模态逻辑的扩展
我已经用Haskell编写了一些用于命题逻辑建模的代码Haskell中命题逻辑到模态逻辑的扩展,haskell,modal-logic,Haskell,Modal Logic,我已经用Haskell编写了一些用于命题逻辑建模的代码 data Formula = Prop {propName :: String} | Neg Formula | Conj Formula Formula | Disj Formula Formula | Impl Formula Formula | BiImpl Formula Formula deri
data Formula = Prop {propName :: String}
| Neg Formula
| Conj Formula Formula
| Disj Formula Formula
| Impl Formula Formula
| BiImpl Formula Formula
deriving (Eq,Ord)
但是,由于数据类型是封闭的,因此没有自然的方法将其扩展到模态逻辑。
因此,我认为我应该使用类来代替。这样,我以后可以很容易地在不同的模块中添加新的语言特性。问题是我不知道怎么写。我想要如下的东西
type PropValue = (String,Bool) -- for example ("p",True) states that proposition p is true
type Valuation = [PropValue]
class Formula a where
evaluate :: a -> Valuation -> Bool
data Proposition = Prop String
instance Formula Proposition where
evaluate (Prop s) val = (s,True) `elem` val
data Conjunction = Conj Formula Formula -- illegal syntax
instance Formula Conjunction where
evaluate (Conj φ ψ) v = evaluate φ v && evaluate ψ v
当然,错误在于连接词的定义。但是,我不清楚如何重写它以使其工作。这应该可以工作:
data Conjunction f = Conj f f
instance Formula f => Formula (Conjunction f) where
evaluate (Conj φ ψ) v = evaluate φ v && evaluate ψ v
但是,我不确定类型类是否是您想要实现的目标的正确工具
也许您可以尝试使用显式类型级函子并在其上循环:
-- functor for plain formulae
data FormulaF f = Prop {propName :: String}
| Neg f
| Conj f f
| Disj f f
| Impl f f
| BiImpl f f
-- plain formula
newtype Formula = F {unF :: FormulaF Formula}
-- functor adding a modality
data ModalF f = Plain f
| MyModality f
-- modal formula
newtype Modal = M {unM :: ModalF Modal}
是的,这并不十分方便,因为构造函数,例如F,M,Plain
有时会造成阻碍。但是,与类型类不同,您可以在这里使用模式匹配
作为另一种选择,使用GADT:
data Plain
data Mod
data Formula t where
Prop {propName :: String} :: Formula t
Neg :: Formula t -> Formula t
Conj :: Formula t -> Formula t -> Formula t
Disj :: Formula t -> Formula t -> Formula t
Impl :: Formula t -> Formula t -> Formula t
BiImpl :: Formula t -> Formula t -> Formula t
MyModality :: Formula Mod -> Formula Mod
type PlainFormula = Formula Plain
type ModalFormula = Formula Mod
谢谢,您的第一个解决方案似乎有效。不过,我还将研究您的其他解决方案,因为我相信数据类型上下文在不久的将来将被弃用,请参阅。GADT似乎不是我需要的解决方案,因为我希望能够在不同的模块中定义不同的运算符。例如,PropLogic.hs中的Conj和Disj运算符、ModalLogic.hs中的Box运算符以及PredLogic.hs中的ForAll量词。@匿名数据类型上下文确实应该避免,但我没有使用它们(您也没有)。这些上下文是
数据(Ord a)=>集合a=…
中的上下文。出现在类
或实例
中的上下文不是数据类型上下文,不会消失。如果您喜欢阅读,您可能会发现有帮助。