initial handling of rules
This commit is contained in:
parent
5caf061fce
commit
2f93c494be
@ -11,7 +11,7 @@ import Data.Set (Set)
|
|||||||
import Data.Set qualified as Set
|
import Data.Set qualified as Set
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Datalog.DatalogParser
|
import Datalog.DatalogParser(parseDatalog, Literal(Literal), Statement(..))
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Text.Megaparsec (ParseErrorBundle)
|
import Text.Megaparsec (ParseErrorBundle)
|
||||||
import Data.Void
|
import Data.Void
|
||||||
@ -71,6 +71,21 @@ withFacts facts =
|
|||||||
newRelations = Map.insert relationName newRelation relations
|
newRelations = Map.insert relationName newRelation relations
|
||||||
newConstants = Set.union constants $ Set.fromList terms
|
newConstants = Set.union constants $ Set.fromList terms
|
||||||
|
|
||||||
|
withFactsAndRules :: [Text] -> [Text] -> NaiveDatabase
|
||||||
|
withFactsAndRules facts rules =
|
||||||
|
foldl addRule (withFacts facts) (extractRule <$> rules) where
|
||||||
|
extractRule:: Text -> (Literal, [Literal])
|
||||||
|
extractRule ruleText =
|
||||||
|
case (parseDatalog ruleText) of
|
||||||
|
Right (Rule lhs rhs) -> (lhs, rhs)
|
||||||
|
Right otherStatement -> throw $ NonRuleException ruleText otherStatement
|
||||||
|
Left ex -> throw $ CannotParseStatementException ruleText ex
|
||||||
|
addRule :: NaiveDatabase -> Literal -> [Literal] -> NaiveDatabase
|
||||||
|
addRule (NaiveDatabase relations constants) (Literal neg relationName terms) body =
|
||||||
|
NaiveDatabase newRelations newConstants where
|
||||||
|
newRelations = relations
|
||||||
|
newConstants = constants
|
||||||
|
|
||||||
query :: NaiveDatabase -> Text -> Text
|
query :: NaiveDatabase -> Text -> Text
|
||||||
query db qText =
|
query db qText =
|
||||||
case (parseDatalog qText) of
|
case (parseDatalog qText) of
|
||||||
@ -81,6 +96,7 @@ query db qText =
|
|||||||
data NaiveDatabaseException
|
data NaiveDatabaseException
|
||||||
= CannotParseStatementException Text (ParseErrorBundle Text Void) |
|
= CannotParseStatementException Text (ParseErrorBundle Text Void) |
|
||||||
NonFactException Text Statement |
|
NonFactException Text Statement |
|
||||||
|
NonRuleException Text Statement |
|
||||||
NonQueryException Text Statement |
|
NonQueryException Text Statement |
|
||||||
BadArityException Text Int
|
BadArityException Text Int
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|||||||
@ -35,6 +35,19 @@ spec = do
|
|||||||
("parent",
|
("parent",
|
||||||
Relation 2 $ Set.fromList $ [Sym <$> ["bob", "carol"]])
|
Relation 2 $ Set.fromList $ [Sym <$> ["bob", "carol"]])
|
||||||
]
|
]
|
||||||
|
it "can ingest facts and rules" $ do
|
||||||
|
let db = NaiveDatabase.withFactsAndRules
|
||||||
|
[ "parent(\"alice\", \"bob\")."
|
||||||
|
, "parent(\"bob\", \"carol\")." ]
|
||||||
|
[ "ancestor(X,Y) :- parent(X,Y)."
|
||||||
|
, "ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y)." ]
|
||||||
|
constants db `shouldBe`
|
||||||
|
(Set.fromList $ Sym <$> ["alice", "bob", "carol"])
|
||||||
|
relations db `shouldBe`
|
||||||
|
Map.fromList [
|
||||||
|
("parent",
|
||||||
|
Relation 2 $ Set.fromList $ [Sym <$> ["bob", "carol"]])
|
||||||
|
]
|
||||||
|
|
||||||
it "can do basic queries" $ do
|
it "can do basic queries" $ do
|
||||||
let db = NaiveDatabase.withFacts
|
let db = NaiveDatabase.withFacts
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user