{- Abstract syntax for first order logic Pedro Vasconcelos, 2009--2010 pbv@dcc.fc.up.pt -} module FOL where import Data.List import Data.Map (Map) import qualified Data.Map as Map import Data.Tree import Zipper hiding (delete) -- type synonyms for names of variables, -- functional and relational symbols type Var = String type Funsym = String type Relsym = String -- first order logic formulas data Formula = TT | FF | Rel Relsym [Term] | Not Formula | And Formula Formula | Or Formula Formula | Implies Formula Formula | Exist Var Formula | Forall Var Formula deriving (Eq,Show,Read) -- instance Show Formula where -- showsPrec p f = showsFormula p f -- first order logic terms data Term = Var Var | Fun Funsym [Term] deriving (Eq, Show, Read) -- substitutions: mappings from variables to terms type Subst = Map Var Term -- a general class for data types with free variables class FV a where fv :: a -> [Var] subst :: Subst -> a -> a -- instance for terms instance FV Term where fv (Var x) = [x] fv (Fun f ts) = concatMap fv ts subst s (Var v) = Map.findWithDefault (Var v) v s subst s (Fun f ts) = Fun f $ map (subst s) ts -- instance for formulas instance FV Formula where fv TT = [] fv FF = [] fv (Rel r ts) = concatMap fv ts fv (Not f) = fv f fv (And f1 f2) = fv f1 ++ fv f2 fv (Or f1 f2) = fv f1 ++ fv f2 fv (Implies f1 f2) = fv f1 ++ fv f2 fv (Exist x f) = delete x (nub (fv f)) fv (Forall x f) = delete x (nub (fv f)) -- subst s TT = TT subst s FF = FF subst s (Rel r ts) = Rel r $ map (subst s) ts subst s (Not f) = Not (subst s f) subst s (And f1 f2) = And (subst s f1) (subst s f2) subst s (Or f1 f2) = Or (subst s f1) (subst s f2) subst s (Implies f1 f2) = Implies (subst s f1) (subst s f2) subst s (Exist x f) = Exist x (subst s' f) where s' = Map.delete x s subst s (Forall x f) = Forall x (subst s' f) where s' = Map.delete x s -- derived instances for parametric types instance FV a => FV [a] where fv ts = concatMap fv ts subst s ts = map (subst s) ts instance (FV a, FV b) => FV (a,b) where fv (u,v) = fv u ++ fv v subst s (u,v) = (subst s u, subst s v) instance (FV a, FV b, FV c) => FV (a,b,c) where fv (u,v,w) = fv u ++ fv v ++ fv w subst s (u,v,w) = (subst s u, subst s v, subst s w) instance FV a => FV (Maybe a) where fv Nothing = [] fv (Just x) = fv x subst s Nothing = Nothing subst s (Just x)= Just (subst s x) instance FV a => FV (Tree a) where fv (Node n ts) = fv n ++ concatMap fv ts subst s (Node n ts) = Node (subst s n) (map (subst s) ts) instance FV a => FV (TreeLoc a) where fv (Loc t l r ps) = fv t ++ fv l ++ fv r ++ fv ps subst s (Loc t l r ps) = Loc (subst s t) (subst s l) (subst s r) (subst s ps)