lift addFact
This commit is contained in:
parent
e01a1ba3df
commit
b8db9477c0
@ -23,5 +23,7 @@ class DatalogDB db where
|
|||||||
emptyDB :: db
|
emptyDB :: db
|
||||||
lookupRelation :: db -> Text -> Maybe Relation
|
lookupRelation :: db -> Text -> Maybe Relation
|
||||||
insertRelation :: db -> Relation -> db
|
insertRelation :: db -> Relation -> db
|
||||||
|
addFact :: Literal -> db -> db
|
||||||
addRule :: (Literal, [Literal]) -> db -> db
|
addRule :: (Literal, [Literal]) -> db -> db
|
||||||
addConstants :: db -> Set Constant -> db
|
addConstants :: db -> Set Constant -> db
|
||||||
|
|
||||||
|
|||||||
@ -45,6 +45,15 @@ instance DatalogDB NaiveDatabase where
|
|||||||
relations = Map.insert (_name relation) relation (relations db)
|
relations = Map.insert (_name relation) relation (relations db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addFact :: Literal -> NaiveDatabase -> NaiveDatabase
|
||||||
|
addFact (Literal neg relationName terms) db@(NaiveDatabase relationMap constantSet) =
|
||||||
|
NaiveDatabase newRelationMap newConstantSet
|
||||||
|
where
|
||||||
|
newArity = length terms
|
||||||
|
newRelation = lookupRelation0 relationName db newArity (Set.singleton terms)
|
||||||
|
newRelationMap = Map.insert relationName newRelation relationMap
|
||||||
|
newConstantSet = Set.union constantSet $ Set.fromList terms
|
||||||
|
|
||||||
addRule :: (Literal, [Literal]) -> NaiveDatabase -> NaiveDatabase
|
addRule :: (Literal, [Literal]) -> NaiveDatabase -> NaiveDatabase
|
||||||
addRule (ruleHead, body) db =
|
addRule (ruleHead, body) db =
|
||||||
NaiveDatabase relationMap' constants' where
|
NaiveDatabase relationMap' constants' where
|
||||||
@ -99,7 +108,7 @@ lookupRelation000 relationName db newArity tuples update =
|
|||||||
_tuples = Set.union tuples $ _tuples relation
|
_tuples = Set.union tuples $ _tuples relation
|
||||||
}
|
}
|
||||||
|
|
||||||
withFacts :: [Text] -> NaiveDatabase
|
withFacts :: DatalogDB db => [Text] -> db
|
||||||
withFacts =
|
withFacts =
|
||||||
foldr (addFact . extractFact) emptyDB
|
foldr (addFact . extractFact) emptyDB
|
||||||
where
|
where
|
||||||
@ -109,14 +118,6 @@ withFacts =
|
|||||||
Right (Fact fact) -> fact
|
Right (Fact fact) -> fact
|
||||||
Right otherStatement -> throw $ NonFactException factText otherStatement
|
Right otherStatement -> throw $ NonFactException factText otherStatement
|
||||||
Left ex -> throw $ CannotParseStatementException factText ex
|
Left ex -> throw $ CannotParseStatementException factText ex
|
||||||
addFact :: Literal -> NaiveDatabase -> NaiveDatabase
|
|
||||||
addFact (Literal neg relationName terms) db@(NaiveDatabase relationMap constantSet) =
|
|
||||||
NaiveDatabase newRelationMap newConstantSet
|
|
||||||
where
|
|
||||||
newArity = length terms
|
|
||||||
newRelation = lookupRelation0 relationName db newArity (Set.singleton terms)
|
|
||||||
newRelationMap = Map.insert relationName newRelation relationMap
|
|
||||||
newConstantSet = Set.union constantSet $ Set.fromList terms
|
|
||||||
|
|
||||||
data (DatalogDB db) => RuleContext db = RuleContext
|
data (DatalogDB db) => RuleContext db = RuleContext
|
||||||
{ __relation :: Relation
|
{ __relation :: Relation
|
||||||
@ -126,15 +127,7 @@ data (DatalogDB db) => RuleContext db = RuleContext
|
|||||||
, _db :: db
|
, _db :: db
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | equivalent(Q,Q) :- . |
|
digestHead :: (DatalogDB db) => db -> Relation -> Literal -> RuleContext db
|
||||||
-- could be equivalent(Q, 3, 'zzz, Q, R)
|
|
||||||
-- terms = Var Q, Num 3, Sym zzz, Var Q, Var R
|
|
||||||
-- want to convert this to:
|
|
||||||
-- (need constants 3, 'zzz)
|
|
||||||
-- entries = [RuleElement] = (RuleElement 0), RuleElement Num 3, RuleElement Sym zzz, (RuleElement 0), (RuleElement 1)
|
|
||||||
-- variableNames = ["Q" "R"]
|
|
||||||
|
|
||||||
digestHead :: forall db . (DatalogDB db) => db -> Relation -> Literal -> RuleContext db
|
|
||||||
digestHead db relation (Literal neg relationName terms) =
|
digestHead db relation (Literal neg relationName terms) =
|
||||||
RuleContext
|
RuleContext
|
||||||
{ __relation = relation
|
{ __relation = relation
|
||||||
@ -150,7 +143,7 @@ digestHead db relation (Literal neg relationName terms) =
|
|||||||
extractConstant :: RuleElement -> Maybe Constant
|
extractConstant :: RuleElement -> Maybe Constant
|
||||||
extractConstant (RuleElementConstant constant) = Just constant
|
extractConstant (RuleElementConstant constant) = Just constant
|
||||||
extractConstant _ = Nothing
|
extractConstant _ = Nothing
|
||||||
digestBody :: forall db . (DatalogDB db) => Literal -> RuleContext db -> RuleContext db
|
digestBody :: (DatalogDB db) => Literal -> RuleContext db -> RuleContext db
|
||||||
digestBody (Literal neg subRelationName subTerms) context =
|
digestBody (Literal neg subRelationName subTerms) context =
|
||||||
context {
|
context {
|
||||||
_variableNames = variableNames
|
_variableNames = variableNames
|
||||||
@ -173,11 +166,13 @@ digestBody (Literal neg subRelationName subTerms) context =
|
|||||||
toRuleElement :: Term -> RuleElement
|
toRuleElement :: Term -> RuleElement
|
||||||
toRuleElement (Var varName) = RuleElementVariable $ lookupVariable varName variableNames
|
toRuleElement (Var varName) = RuleElementVariable $ lookupVariable varName variableNames
|
||||||
toRuleElement constant = RuleElementConstant constant
|
toRuleElement constant = RuleElementConstant constant
|
||||||
|
|
||||||
lookupVariable :: Text -> [Text] -> Int
|
lookupVariable :: Text -> [Text] -> Int
|
||||||
lookupVariable varName variableNames =
|
lookupVariable varName variableNames =
|
||||||
case elemIndex varName variableNames of
|
case elemIndex varName variableNames of
|
||||||
Just index -> index
|
Just index -> index
|
||||||
Nothing -> throw $ VariableLookupException varName variableNames
|
Nothing -> throw $ VariableLookupException varName variableNames
|
||||||
|
|
||||||
headTermToElement :: [Text] -> Term -> RuleElement
|
headTermToElement :: [Text] -> Term -> RuleElement
|
||||||
headTermToElement variableNames (Var name) =
|
headTermToElement variableNames (Var name) =
|
||||||
RuleElementVariable $ lookupVariable name variableNames
|
RuleElementVariable $ lookupVariable name variableNames
|
||||||
@ -186,7 +181,7 @@ headTermToElement _ constant = RuleElementConstant constant
|
|||||||
withFactsAndRules :: [Text] -> [Text] -> NaiveDatabase
|
withFactsAndRules :: [Text] -> [Text] -> NaiveDatabase
|
||||||
withFactsAndRules facts = foldr (addRule . extractRule) (withFacts facts)
|
withFactsAndRules facts = foldr (addRule . extractRule) (withFacts facts)
|
||||||
|
|
||||||
query :: NaiveDatabase -> Text -> Text
|
query :: forall db . (DatalogDB db) => db -> Text -> Text
|
||||||
query db qText =
|
query db qText =
|
||||||
case parseDatalog qText of
|
case parseDatalog qText of
|
||||||
Right (Query texts literals) -> "#NYI"
|
Right (Query texts literals) -> "#NYI"
|
||||||
|
|||||||
@ -233,7 +233,7 @@ spec = do
|
|||||||
`shouldBe` Set.empty
|
`shouldBe` Set.empty
|
||||||
|
|
||||||
it "can do basic queries" do
|
it "can do basic queries" do
|
||||||
let db =
|
let db :: NaiveDatabase =
|
||||||
NaiveDatabase.withFacts
|
NaiveDatabase.withFacts
|
||||||
[ "parent(\"alice\", \"bob\")."
|
[ "parent(\"alice\", \"bob\")."
|
||||||
, "parent(\"bob\", \"carol\")."
|
, "parent(\"bob\", \"carol\")."
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user