logic-classes-1.1: Data/Logic/Types/Harrison/FOL.hs
{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, RankNTypes, ScopedTypeVariables,
TypeFamilies, TypeSynonymInstances #-}
{-# OPTIONS_GHC -Wall -fno-warn-orphans #-}
module Data.Logic.Types.Harrison.FOL
( TermType(..)
, FOL(..)
, Function(..)
) where
import Data.Generics (Data, Typeable)
import Data.Logic.Classes.Arity
import Data.Logic.Classes.Apply (Apply(..), showApply)
import Data.Logic.Classes.Combine (Combination(..), BinOp(..))
import Data.Logic.Classes.Constants (Constants(fromBool), asBool)
import Data.Logic.Classes.FirstOrder (FirstOrderFormula(..), showFirstOrder)
import Data.Logic.Classes.Skolem (Skolem(..))
import Data.Logic.Classes.Term (Term(vt, foldTerm, fApp))
import Data.Logic.Classes.Variable (Variable(..))
import qualified Data.Logic.Classes.Term as C
import qualified Data.Logic.Classes.FirstOrder as C
import Data.Logic.Types.Harrison.Formulas.FirstOrder (Formula(..))
import qualified Data.Logic.Types.Harrison.Formulas.FirstOrder as H
import qualified Data.Set as Set
import Prelude hiding (pred)
import Text.PrettyPrint (text)
-- -------------------------------------------------------------------------
-- Terms.
-- -------------------------------------------------------------------------
data TermType
= Var String
| Fn Function [TermType]
deriving (Eq, Ord)
data FOL = R String [TermType] deriving (Eq, Ord, Show)
instance Show TermType where
show (Var v) = "var " ++ show v
show (Fn f ts) = "fApp " ++ show f ++ " " ++ show ts
instance Apply FOL String TermType where
foldApply f tf (R p ts) = maybe (f p ts) tf (asBool p)
apply' = R
-- | This is probably dangerous.
instance Constants String where
fromBool True = "true"
fromBool False = "false"
instance Constants FOL where
fromBool x = R (fromBool x) []
instance FirstOrderFormula (Formula FOL) FOL String where
-- type C.Term (Formula FOL) = Term
-- type V (Formula FOL) = String
-- type Pr (Formula FOL) = String
-- type Fn (Formula FOL) = String -- ^ Atomic function type
-- quant C.Exists v fm = H.Exists v fm
-- quant C.Forall v fm = H.Forall v fm
for_all = H.Forall
exists = H.Exists
atomic = Atom
foldFirstOrder qu co tf at fm =
case fm of
F -> tf False
T -> tf True
Atom atom -> at atom
Not fm' -> co ((:~:) fm')
And fm1 fm2 -> co (BinOp fm1 (:&:) fm2)
Or fm1 fm2 -> co (BinOp fm1 (:|:) fm2)
Imp fm1 fm2 -> co (BinOp fm1 (:=>:) fm2)
Iff fm1 fm2 -> co (BinOp fm1 (:<=>:) fm2)
H.Forall v fm' -> qu C.Forall v fm'
H.Exists v fm' -> qu C.Exists v fm'
instance Arity String where
arity _ = Nothing
-- | The Harrison book uses String for atomic function, but we need
-- something a little more type safe because of our Skolem class.
data Function
= FName String
| Skolem Int
deriving (Eq, Ord, Data, Typeable, Show)
instance Skolem Function where
toSkolem = Skolem
fromSkolem (Skolem n) = Just n
fromSkolem _ = Nothing
instance Term TermType String Function where
-- type V Term = String
-- type Fn Term = String
vt = Var
fApp = Fn
foldTerm vfn _ (Var x) = vfn x
foldTerm _ ffn (Fn f ts) = ffn f ts
zipTerms = undefined
instance Variable String where
variant x vars = if Set.member x vars then variant (x ++ "'") vars else x
prefix p x = p ++ x
prettyVariable = text
instance Show (Formula FOL) where
show = showFirstOrder showApply