adding rules to relations
This commit is contained in:
parent
2f93c494be
commit
925af95464
@ -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(parseDatalog, Literal(Literal), Statement(..))
|
import Datalog.DatalogParser(parseDatalog, Literal(Literal), Statement(..), Term, Head (HeadSingle))
|
||||||
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
|
||||||
@ -27,9 +27,20 @@ data NaiveDatabase = NaiveDatabase {
|
|||||||
constants :: Set Constant
|
constants :: Set Constant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data BodyEntry = -- entry occurring in a head or body relation - constant or variable
|
||||||
|
BodyEntryConstant Constant |
|
||||||
|
BodyEntryVariable Text
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data RelationRule = RelationRule {
|
||||||
|
headVariables :: [BodyEntry],
|
||||||
|
body :: [(Relation, [BodyEntry])]
|
||||||
|
} deriving (Show, Eq)
|
||||||
|
|
||||||
data Relation = Relation {
|
data Relation = Relation {
|
||||||
arity :: Int,
|
arity :: Int,
|
||||||
tuples :: Set [Constant]
|
tuples :: Set [Constant],
|
||||||
|
rules :: [RelationRule]
|
||||||
} deriving (Show, Eq)
|
} deriving (Show, Eq)
|
||||||
|
|
||||||
-- newtype RelationId = RelationId Text
|
-- newtype RelationId = RelationId Text
|
||||||
@ -63,10 +74,10 @@ withFacts facts =
|
|||||||
newArity = length terms
|
newArity = length terms
|
||||||
newRelation =
|
newRelation =
|
||||||
case Map.lookup relationName relations of
|
case Map.lookup relationName relations of
|
||||||
Nothing -> Relation (length terms) (Set.singleton terms)
|
Nothing -> Relation (length terms) (Set.singleton terms) []
|
||||||
Just relation ->
|
Just relation ->
|
||||||
if (arity relation == newArity)
|
if (arity relation == newArity)
|
||||||
then Relation (length terms) (Set.singleton terms)
|
then Relation (length terms) (Set.singleton terms) []
|
||||||
else throw $ BadArityException relationName newArity
|
else throw $ BadArityException relationName newArity
|
||||||
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
|
||||||
@ -77,11 +88,11 @@ withFactsAndRules facts rules =
|
|||||||
extractRule:: Text -> (Literal, [Literal])
|
extractRule:: Text -> (Literal, [Literal])
|
||||||
extractRule ruleText =
|
extractRule ruleText =
|
||||||
case (parseDatalog ruleText) of
|
case (parseDatalog ruleText) of
|
||||||
Right (Rule lhs rhs) -> (lhs, rhs)
|
Right (Rule (HeadSingle lhs) rhs) -> (lhs, rhs)
|
||||||
Right otherStatement -> throw $ NonRuleException ruleText otherStatement
|
Right otherStatement -> throw $ NonRuleException ruleText otherStatement
|
||||||
Left ex -> throw $ CannotParseStatementException ruleText ex
|
Left ex -> throw $ CannotParseStatementException ruleText ex
|
||||||
addRule :: NaiveDatabase -> Literal -> [Literal] -> NaiveDatabase
|
addRule :: NaiveDatabase -> (Literal, [Literal]) -> NaiveDatabase
|
||||||
addRule (NaiveDatabase relations constants) (Literal neg relationName terms) body =
|
addRule (NaiveDatabase relations constants) ((Literal neg relationName terms), body) =
|
||||||
NaiveDatabase newRelations newConstants where
|
NaiveDatabase newRelations newConstants where
|
||||||
newRelations = relations
|
newRelations = relations
|
||||||
newConstants = constants
|
newConstants = constants
|
||||||
|
|||||||
@ -33,7 +33,7 @@ spec = do
|
|||||||
relations db `shouldBe`
|
relations db `shouldBe`
|
||||||
Map.fromList [
|
Map.fromList [
|
||||||
("parent",
|
("parent",
|
||||||
Relation 2 $ Set.fromList $ [Sym <$> ["bob", "carol"]])
|
Relation 2 (Set.fromList ([Sym <$> ["bob", "carol"]])) [] )
|
||||||
]
|
]
|
||||||
it "can ingest facts and rules" $ do
|
it "can ingest facts and rules" $ do
|
||||||
let db = NaiveDatabase.withFactsAndRules
|
let db = NaiveDatabase.withFactsAndRules
|
||||||
@ -46,7 +46,7 @@ spec = do
|
|||||||
relations db `shouldBe`
|
relations db `shouldBe`
|
||||||
Map.fromList [
|
Map.fromList [
|
||||||
("parent",
|
("parent",
|
||||||
Relation 2 $ Set.fromList $ [Sym <$> ["bob", "carol"]])
|
Relation 2 (Set.fromList ([Sym <$> ["bob", "carol"]])) [] )
|
||||||
]
|
]
|
||||||
|
|
||||||
it "can do basic queries" $ do
|
it "can do basic queries" $ do
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user