logic-classes-1.1: Data/Logic/Types/Propositional.hs
{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses #-}
module Data.Logic.Types.Propositional where
import Data.Generics (Data, Typeable)
import Data.Logic.Classes.Combine (Combinable(..), Combination(..), BinOp(..))
import Data.Logic.Classes.Constants (Constants(..), asBool)
import Data.Logic.Classes.Negate (Negatable(..))
import Data.Logic.Classes.Propositional (PropositionalFormula(..))
-- | The range of a formula is {True, False} when it has no free variables.
data Formula atom
= Combine (Combination (Formula atom))
| Atom atom
-- Note that a derived Eq instance is not going to tell us that
-- a&b is equal to b&a, let alone that ~(a&b) equals (~a)|(~b).
deriving (Eq,Ord,Data,Typeable)
instance Negatable (Formula atom) where
negatePrivate x = Combine ((:~:) x)
foldNegation normal inverted (Combine ((:~:) x)) = foldNegation inverted normal x
foldNegation normal _ x = normal x
instance (Constants atom, Ord atom) => Combinable (Formula atom) where
x .<=>. y = Combine (BinOp x (:<=>:) y)
x .=>. y = Combine (BinOp x (:=>:) y)
x .|. y = Combine (BinOp x (:|:) y)
x .&. y = Combine (BinOp x (:&:) y)
instance Constants atom => Constants (Formula atom) where
fromBool = Atom . fromBool
instance (Constants atom, Ord atom) => PropositionalFormula (Formula atom) atom where
atomic a = Atom a
foldPropositional co tf at formula =
case formula of
Combine x -> co x
Atom x -> maybe (at x) tf (asBool x)