-- | The 'IsFormula' class contains definitions for the boolean true -- and false values, and methods for traversing the atoms of a formula. {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} module Data.Logic.ATP.Formulas ( IsAtom , IsFormula(AtomOf, true, false, asBool, atomic, overatoms, onatoms) , (⊥), (⊤) , fromBool , prettyBool , atom_union ) where import Data.Logic.ATP.Pretty (Doc, HasFixity, Pretty, text) import Data.Set as Set (Set, empty, union) import Prelude hiding (negate) -- | Basic properties of an atomic formula class (Ord atom, Show atom, HasFixity atom, Pretty atom) => IsAtom atom -- | Class associating a formula type with its atom (atomic formula) type. class (Pretty formula, HasFixity formula, IsAtom (AtomOf formula)) => IsFormula formula where type AtomOf formula -- ^ AtomOf is a function that maps the formula type to the -- associated atomic formula type true :: formula -- ^ The true element false :: formula -- ^ The false element asBool :: formula -> Maybe Bool -- ^ If the arugment is true or false return the corresponding -- 'Bool', otherwise return 'Nothing'. atomic :: AtomOf formula -> formula -- ^ Build a formula from an atom. overatoms :: (AtomOf formula -> r -> r) -> formula -> r -> r -- ^ Formula analog of iterator 'foldr'. onatoms :: (AtomOf formula -> AtomOf formula) -> formula -> formula -- ^ Apply a function to the atoms, otherwise keeping structure (new sig) (⊤) :: IsFormula p => p (⊤) = true (⊥) :: IsFormula p => p (⊥) = false fromBool :: IsFormula formula => Bool -> formula fromBool True = true fromBool False = false prettyBool :: Bool -> Doc prettyBool True = text "⊤" prettyBool False = text "⊥" -- | Special case of a union of the results of a function over the atoms. atom_union :: (IsFormula formula, Ord r) => (AtomOf formula -> Set r) -> formula -> Set r atom_union f fm = overatoms (\h t -> Set.union (f h) t) fm Set.empty