2026-01-12 16:10:51 -05:00
|
|
|
module Datalog.Syntax where
|
|
|
|
|
|
2026-01-16 01:05:19 -05:00
|
|
|
import Data.Char (isUpper)
|
2026-01-12 16:10:51 -05:00
|
|
|
import Data.Text (Text)
|
2026-01-16 01:05:19 -05:00
|
|
|
import Data.Text qualified as T
|
|
|
|
|
import Data.Set qualified as Set
|
|
|
|
|
import Data.Set (Set)
|
2026-01-12 16:10:51 -05:00
|
|
|
|
2026-01-16 01:05:19 -05:00
|
|
|
newtype ConId = ConId Text
|
|
|
|
|
deriving (Eq, Ord, Show)
|
|
|
|
|
|
|
|
|
|
newtype VarId = VarId Text
|
|
|
|
|
deriving (Eq, Ord, Show)
|
|
|
|
|
|
|
|
|
|
newtype RelId = RelId Text
|
|
|
|
|
deriving (Eq, Ord, Show)
|
2026-01-12 16:10:51 -05:00
|
|
|
|
2026-01-16 01:05:19 -05:00
|
|
|
data Term = Con ConId | Var VarId
|
2026-01-12 16:10:51 -05:00
|
|
|
deriving (Eq, Ord, Show)
|
|
|
|
|
|
2026-01-16 01:05:19 -05:00
|
|
|
con :: Text -> Term
|
|
|
|
|
con = Con . ConId
|
|
|
|
|
|
|
|
|
|
var :: Text -> Term
|
|
|
|
|
var = Var . VarId
|
|
|
|
|
|
|
|
|
|
term :: Text -> Term
|
|
|
|
|
term t = if not (T.null t) && isUpper (T.head t) then var t else con t
|
|
|
|
|
|
|
|
|
|
data Atom = Atom RelId [Term]
|
2026-01-12 16:10:51 -05:00
|
|
|
deriving (Eq, Ord, Show)
|
|
|
|
|
|
2026-01-16 01:05:19 -05:00
|
|
|
atom :: Text -> [Text] -> Atom
|
|
|
|
|
atom relName args = Atom (RelId relName) (map term args)
|
|
|
|
|
|
2026-01-12 16:10:51 -05:00
|
|
|
data Rule = Atom :- [Atom]
|
|
|
|
|
deriving (Eq, Ord, Show)
|
|
|
|
|
|
|
|
|
|
data Program = Program [Rule]
|
|
|
|
|
deriving (Eq, Ord, Show)
|
2026-01-16 01:05:19 -05:00
|
|
|
|
|
|
|
|
class HasConstants a where
|
|
|
|
|
constants :: a -> Set ConId
|
|
|
|
|
|
|
|
|
|
instance HasConstants Term where
|
|
|
|
|
constants t = case t of
|
|
|
|
|
Con x -> Set.singleton x
|
|
|
|
|
Var _ -> Set.empty
|
|
|
|
|
|
|
|
|
|
instance HasConstants a => HasConstants [a] where
|
|
|
|
|
constants xs = Set.unions (map constants xs)
|
|
|
|
|
|
|
|
|
|
instance HasConstants Atom where
|
|
|
|
|
constants (Atom _ ts) = constants ts
|
|
|
|
|
|
|
|
|
|
instance HasConstants Rule where
|
|
|
|
|
constants (h :- b) = Set.union (constants h) (constants b)
|
|
|
|
|
|
|
|
|
|
instance HasConstants Program where
|
|
|
|
|
constants (Program rs) = constants rs
|