68 lines
2.0 KiB
Haskell
Raw Normal View History

2026-01-21 11:24:30 +00:00
{-# HLINT ignore "Redundant flip" #-}
2026-01-21 17:11:13 +00:00
{-# LANGUAGE ImportQualifiedPost #-}
2026-01-23 18:12:47 +00:00
{-# LANGUAGE ScopedTypeVariables #-}
2026-01-27 16:41:33 +00:00
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
2026-01-29 16:42:53 +00:00
{-# LANGUAGE InstanceSigs #-}
2026-01-29 17:27:11 +00:00
{-# LANGUAGE BlockArguments #-}
2026-01-27 16:41:33 +00:00
2026-01-30 15:39:17 +00:00
module Datalog.InMemoryDB where
2026-01-21 11:24:30 +00:00
2026-01-27 16:41:33 +00:00
import Control.Exception.Base
2026-01-21 11:24:30 +00:00
import Data.Map (Map)
2026-01-27 16:41:33 +00:00
import Data.Map qualified as Map
2026-01-21 11:24:30 +00:00
import Data.Set (Set)
2026-01-21 17:11:13 +00:00
import Data.Set qualified as Set
import Data.Text (Text)
2026-01-30 14:47:29 +00:00
import Datalog.DatalogParser (Literal (..), Statement (..), parseDatalog)
import Datalog.Rules
2026-01-30 10:27:26 +00:00
import Datalog.DatalogDB
2026-01-21 11:24:30 +00:00
2026-01-30 15:39:17 +00:00
data InMemoryDB = InMemoryDB
2026-01-27 16:41:33 +00:00
{ relations :: Map RelationId Relation
, constants :: Set Constant
} deriving (Show, Eq)
2026-01-21 17:11:13 +00:00
2026-01-30 15:39:17 +00:00
instance DatalogDB InMemoryDB where
emptyDB :: InMemoryDB
emptyDB = InMemoryDB
2026-01-27 16:41:33 +00:00
{ relations = Map.empty
, constants = Set.empty -- the Herbrand universe
}
2026-01-21 17:11:13 +00:00
2026-01-30 15:39:17 +00:00
lookupRelation :: InMemoryDB -> Text -> Maybe Relation
2026-01-29 17:02:27 +00:00
lookupRelation db relationName =
Map.lookup relationName $ relations db
2026-01-30 15:39:17 +00:00
insertRelation :: InMemoryDB -> Relation -> InMemoryDB
2026-01-29 17:27:11 +00:00
insertRelation db relation =
db {
relations = Map.insert (_name relation) relation (relations db)
}
2026-01-30 15:39:17 +00:00
addConstants :: InMemoryDB -> Set Constant -> InMemoryDB
2026-01-30 10:55:19 +00:00
addConstants db newConstants =
db {
constants = Set.union newConstants (constants db)
}
2026-01-30 12:53:40 +00:00
withFacts :: DatalogDB db => [Text] -> db
2026-01-28 12:39:32 +00:00
withFacts =
foldr (addFact . extractFact) emptyDB
2026-01-27 16:41:33 +00:00
where
extractFact :: Text -> Literal
extractFact factText =
2026-01-27 17:33:44 +00:00
case parseDatalog factText of
2026-01-27 16:41:33 +00:00
Right (Fact fact) -> fact
Right otherStatement -> throw $ NonFactException factText otherStatement
Left ex -> throw $ CannotParseStatementException factText ex
2026-01-23 18:12:47 +00:00
2026-01-30 15:39:17 +00:00
withFactsAndRules :: [Text] -> [Text] -> InMemoryDB
2026-01-30 11:00:24 +00:00
withFactsAndRules facts = foldr (addRule . extractRule) (withFacts facts)
2026-01-30 12:53:40 +00:00
query :: forall db . (DatalogDB db) => db -> Text -> Text
2026-01-21 17:11:13 +00:00
query db qText =
2026-01-27 17:27:18 +00:00
case parseDatalog qText of
2026-01-21 17:11:13 +00:00
Right (Query texts literals) -> "#NYI"
Right otherStatement -> throw $ NonQueryException qText otherStatement
Left ex -> throw $ CannotParseStatementException qText ex