Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending propositional logic to modal logic in Haskell

I have written some code in Haskell for modeling propositional logic

data Formula = Prop {propName :: String} 
            | Neg Formula 
            | Conj Formula Formula 
            | Disj Formula Formula
            | Impl Formula Formula 
            | BiImpl Formula Formula 
    deriving (Eq,Ord)

However, there is no natural way to extend this to Modal Logic, since the data type is closed. Therefore, I thought I should use classes instead. That way, I can easily add new language features in different modules later on. The problem is that I don't exactly know how to write it. I would like something like the following

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

The mistake is of course in the definition of Conjunction. However, it is unclear to me how I could rewrite it so that it works.

like image 887
Jetze Avatar asked Sep 28 '14 10:09

Jetze


1 Answers

This should work:

data Conjunction f = Conj f f

instance Formula f => Formula (Conjunction f) where
    evaluate (Conj φ ψ) v = evaluate φ v && evaluate ψ v

However, I am not sure type classes are the right tool for what you are trying to achieve.


Maybe you could give a whirl to using explicit type level functors and recurring over them:

-- 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}

Yes, this is not terribly convenient since constructors such as F,M,Plain get sometimes in the way. But, unlike type classes, you can use pattern matching here.


As another option, use a 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
like image 99
chi Avatar answered Dec 27 '22 06:12

chi