{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# HLINT ignore "Redundant flip" #-} {-# LANGUAGE ImportQualifiedPost #-} module Datalog.NaiveDatabase where import Data.Map (Map) import Data.Set (Set) import Data.Set qualified as Set import Data.Text (Text) import qualified Data.Text as T import Datalog.DatalogParser import qualified Data.Map as Map import Text.Megaparsec (ParseErrorBundle) import Data.Void import Control.Exception (Exception) import Control.Exception.Base data Value = ValueInt Int | ValueSymbol String data NaiveDatabase = NaiveDatabase { relations :: Map RelationId Relation, constants :: Set ConstantId } data Relation = Relation { arity :: Int, tuples :: Set [ConstantId] } newtype RelationId = RelationId Text deriving (Eq, Ord, Show) newtype ConstantId = ConstantId Text deriving (Eq, Ord, Show) emptyDB :: NaiveDatabase emptyDB = NaiveDatabase { relations = Map.empty, constants = Set.empty } withFacts :: [Text] -> NaiveDatabase withFacts facts = foldl addFact emptyDB (extractFact <$> facts) where extractFact:: Text -> Literal extractFact factText = case (parseDatalog factText) of Right (Fact fact) -> fact Right otherStatement -> throw $ NonFactException factText otherStatement Left ex -> throw $ CannotParseStatementException factText ex addFact :: NaiveDatabase -> Literal -> NaiveDatabase addFact db lit = db query :: NaiveDatabase -> Text -> Text query db qText = case (parseDatalog qText) of Right (Query texts literals) -> "#NYI" Right otherStatement -> throw $ NonQueryException qText otherStatement Left ex -> throw $ CannotParseStatementException qText ex data NaiveDatabaseException = CannotParseStatementException Text (ParseErrorBundle Text Void) | NonFactException Text Statement | NonQueryException Text Statement deriving (Show) instance Exception NaiveDatabaseException