module-management-0.20.2: testdata/split-expected/Data/Logic/Classes/Combine.hs
-- | Class Logic defines the basic boolean logic operations,
-- AND, OR, NOT, and so on. Definitions which pertain to both
-- propositional and first order logic are here.
{-# LANGUAGE DeriveDataTypeable #-}
module Data.Logic.Classes.Combine
( Combinable(..)
, Combination(..)
, combine
, BinOp(..)
, binop
-- * Unicode aliases for Combinable class methods
, (∧)
, (∨)
, (⇒)
, (⇔)
-- * Use in Harrison's code
, (==>)
, (<=>)
, prettyBinOp
) where
import Data.Generics (Data, Typeable)
import Data.Logic.Classes.Negate (Negatable, (.~.))
import Data.Logic.Classes.Pretty (Pretty(pretty))
import Text.PrettyPrint (Doc, text)
-- | A type class for logical formulas. Minimal implementation:
-- @
-- (.|.)
-- @
class (Negatable formula) => Combinable formula where
-- | Disjunction/OR
(.|.) :: formula -> formula -> formula
-- | Derived formula combinators. These could (and should!) be
-- overridden with expressions native to the instance.
--
-- | Conjunction/AND
(.&.) :: formula -> formula -> formula
x .&. y = (.~.) ((.~.) x .|. (.~.) y)
-- | Formula combinators: Equivalence
(.<=>.) :: formula -> formula -> formula
x .<=>. y = (x .=>. y) .&. (y .=>. x)
-- | Implication
(.=>.) :: formula -> formula -> formula
x .=>. y = ((.~.) x .|. y)
-- | Reverse implication:
(.<=.) :: formula -> formula -> formula
x .<=. y = y .=>. x
-- | Exclusive or
(.<~>.) :: formula -> formula -> formula
x .<~>. y = ((.~.) x .&. y) .|. (x .&. (.~.) y)
-- | Nor
(.~|.) :: formula -> formula -> formula
x .~|. y = (.~.) (x .|. y)
-- | Nand
(.~&.) :: formula -> formula -> formula
x .~&. y = (.~.) (x .&. y)
infixl 1 .<=>. , .<~>., ⇔, <=>
infixr 2 .=>., ⇒, ==>
infixr 3 .|., ∨
infixl 4 .&., ∧
-- |'Combination' is a helper type used in the signatures of the
-- 'foldPropositional' and 'foldFirstOrder' methods so can represent
-- all the ways that formulas can be combined using boolean logic -
-- negation, logical And, and so forth.
data Combination formula
= BinOp formula BinOp formula
| (:~:) formula
deriving (Eq, Ord, Data, Typeable, Show, Read)
-- | A helper function for building folds:
-- @
-- foldPropositional combine atomic
-- @
-- is a no-op.
combine :: Combinable formula => Combination formula -> formula
combine (BinOp f1 (:<=>:) f2) = f1 .<=>. f2
combine (BinOp f1 (:=>:) f2) = f1 .=>. f2
combine (BinOp f1 (:&:) f2) = f1 .&. f2
combine (BinOp f1 (:|:) f2) = f1 .|. f2
combine ((:~:) f) = (.~.) f
-- | Represents the boolean logic binary operations, used in the
-- Combination type above.
data BinOp
= (:<=>:) -- ^ Equivalence
| (:=>:) -- ^ Implication
| (:&:) -- ^ AND
| (:|:) -- ^ OR
deriving (Eq, Ord, Data, Typeable, Enum, Bounded, Show, Read)
binop :: Combinable formula => formula -> BinOp -> formula -> formula
binop a (:&:) b = a .&. b
binop a (:|:) b = a .|. b
binop a (:=>:) b = a .=>. b
binop a (:<=>:) b = a .<=>. b
(∧) :: Combinable formula => formula -> formula -> formula
(∧) = (.&.)
(∨) :: Combinable formula => formula -> formula -> formula
(∨) = (.|.)
-- | ⇒ can't be a function when -XUnicodeSyntax is enabled.
(⇒) :: Combinable formula => formula -> formula -> formula
(⇒) = (.=>.)
(⇔) :: Combinable formula => formula -> formula -> formula
(⇔) = (.<=>.)
(==>) :: Combinable formula => formula -> formula -> formula
(==>) = (.=>.)
(<=>) :: Combinable formula => formula -> formula -> formula
(<=>) = (.<=>.)
prettyBinOp :: BinOp -> Doc
prettyBinOp (:<=>:) = text "⇔"
prettyBinOp (:=>:) = text "⇒"
prettyBinOp (:&:) = text "∧"
prettyBinOp (:|:) = text "∨"
instance Pretty BinOp where
pretty = prettyBinOp