fixed relation tuples

This commit is contained in:
Felix Dilke 2026-01-26 18:28:15 +00:00
parent d8a1e2f9b1
commit b8e166d867
2 changed files with 26 additions and 40 deletions

View File

@ -74,17 +74,19 @@ withFacts facts =
addFact (NaiveDatabase relationMap constantSet) (Literal neg relationName terms) = addFact (NaiveDatabase relationMap constantSet) (Literal neg relationName terms) =
NaiveDatabase newRelationMap newConstantSet where NaiveDatabase newRelationMap newConstantSet where
newArity = length terms newArity = length terms
newRelation = lookupRelation relationName relationMap newArity terms newRelation = lookupRelation relationName relationMap newArity (Set.singleton terms)
newRelationMap = Map.insert relationName newRelation relationMap newRelationMap = Map.insert relationName newRelation relationMap
newConstantSet = Set.union constantSet $ Set.fromList terms newConstantSet = Set.union constantSet $ Set.fromList terms
lookupRelation :: RelationId -> Map RelationId Relation -> Int -> [Term] -> Relation lookupRelation :: RelationId -> Map RelationId Relation -> Int -> Set [Term] -> Relation
lookupRelation relationName relationMap newArity terms = lookupRelation relationName relationMap newArity tuples =
case Map.lookup relationName relationMap of case Map.lookup relationName relationMap of
Nothing -> Relation relationName newArity (Set.singleton terms) [] Nothing -> Relation relationName newArity tuples []
Just relation -> Just relation ->
if (_arity relation == newArity) if (_arity relation == newArity)
then Relation relationName (length terms) (Set.singleton terms) [] then
let newTuples = Set.union tuples $ _tuples relation
in Relation relationName newArity newTuples []
else throw $ BadArityException relationName newArity else throw $ BadArityException relationName newArity
data ConstraintElement = -- entry occurring in a rule body constraint - constant or variable index data ConstraintElement = -- entry occurring in a rule body constraint - constant or variable index
@ -149,7 +151,7 @@ withFactsAndRules facts rules =
} where } where
relation = __relation context relation = __relation context
newArity = length terms newArity = length terms
subRelation = lookupRelation subRelationName relationMap newArity terms subRelation = lookupRelation subRelationName relationMap newArity Set.empty
relationMap :: Map RelationId Relation = relations (_db context) relationMap :: Map RelationId Relation = relations (_db context)
relationMap' = Map.insert subRelationName subRelation relationMap relationMap' = Map.insert subRelationName subRelation relationMap
extraVariables = toElement <$> terms extraVariables = toElement <$> terms
@ -174,7 +176,7 @@ withFactsAndRules facts rules =
relationName = predName ruleHead relationName = predName ruleHead
terms = arguments ruleHead terms = arguments ruleHead
newArity = length terms newArity = length terms
relation = lookupRelation relationName (relations (_db context)) newArity terms relation = lookupRelation relationName (relations (_db context)) newArity Set.empty
context = RuleContext { context = RuleContext {
__relation = relation, __relation = relation,
_headVariables = [], _headVariables = [],
@ -197,12 +199,6 @@ withFactsAndRules facts rules =
extractVarName :: RuleElement -> Text extractVarName :: RuleElement -> Text
extractVarName (RuleElementVariable varName) = varName extractVarName (RuleElementVariable varName) = varName
extractVarName (RuleElementConstant constant) = throw $ UnexpectedConstantException constant extractVarName (RuleElementConstant constant) = throw $ UnexpectedConstantException constant
-- toBodyConstraint :: (Relation, [RuleElement]) -> BodyConstraint
-- toBodyConstraint (subRelation, ruleElements) =
-- BodyConstraint {
-- _relation = subRelation,
-- _elements = toConstraintElement <$> ruleElements
-- }
newRule = RelationRule { newRule = RelationRule {
headVariables = extractVarName <$> variables', headVariables = extractVarName <$> variables',
body = fromBodyConstraint <$> (_bodyConstraints context'') body = fromBodyConstraint <$> (_bodyConstraints context'')
@ -213,10 +209,6 @@ withFactsAndRules facts rules =
toRuleElement :: ConstraintElement -> RuleElement toRuleElement :: ConstraintElement -> RuleElement
toRuleElement (ConstraintElementConstant constant) = RuleElementConstant constant toRuleElement (ConstraintElementConstant constant) = RuleElementConstant constant
toRuleElement (ConstraintElementIndex index) = variables' !! index toRuleElement (ConstraintElementIndex index) = variables' !! index
-- input is [(Relation, [RuleElement])]
-- bodyConstraint has
-- _relation :: Relation,
-- _elements :: [ConstraintElement]
relation' = Relation { relation' = Relation {
_name = _name relation, _name = _name relation,
_arity = newArity, _arity = newArity,

View File

@ -21,7 +21,7 @@ import qualified Data.Map as Map
spec :: Spec spec :: Spec
spec = do spec = do
describe "dummy test" $ do describe "NaiveDatabase operations" $ do
it "..." $ do it "..." $ do
1 `shouldBe` (1 :: Int) 1 `shouldBe` (1 :: Int)
it "can ingest facts into relations & a universe" $ do it "can ingest facts into relations & a universe" $ do
@ -33,7 +33,7 @@ spec = do
relations db `shouldBe` relations db `shouldBe`
Map.fromList [ Map.fromList [
("parent", ("parent",
Relation "parent" 2 (Set.fromList ([Sym <$> ["bob", "carol"]])) [] ) Relation "parent" 2 (Set.fromList (map (Sym <$>) [["alice", "bob"], ["bob", "carol"]])) [] )
] ]
it "can ingest facts and rules" $ do it "can ingest facts and rules" $ do
let db = NaiveDatabase.withFactsAndRules let db = NaiveDatabase.withFactsAndRules
@ -41,33 +41,28 @@ spec = do
, "parent(\"bob\", \"carol\")." ] , "parent(\"bob\", \"carol\")." ]
[ "ancestor(X,Y) :- parent(X,Y)." [ "ancestor(X,Y) :- parent(X,Y)."
, "ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y)." ] , "ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y)." ]
constants db `shouldBe`
(Set.fromList $ Sym <$> ["alice", "bob", "carol"])
let parentRelation = Relation { let parentRelation = Relation {
_name = "parent", _name = "parent",
_arity = 2, _arity = 2,
_tuples = Set.fromList [ _tuples = Set.fromList $
[Var "X",Var "Z"] map (Sym <$>) [["alice", "bob"], ["bob", "carol"]],
],
_rules = [] _rules = []
} }
let ancestorRelation = Relation { let ancestorRelation = Relation {
_name = "ancestor",
_arity = 2, _arity = 2,
_tuples = Set.fromList [ _name = "ancestor",
[Var "Z",Var "Y"] _tuples = Set.empty,
],
_rules = [] _rules = []
} }
constants db `shouldBe`
(Set.fromList $ Sym <$> ["alice", "bob", "carol"])
relations db `shouldBe` relations db `shouldBe`
Map.fromList [ Map.fromList [
("ancestor", ("ancestor",
Relation { Relation {
_arity = 2, _arity = 2,
_name = "ancestor", _name = "ancestor",
_tuples = Set.fromList [ _tuples = Set.empty,
[Var "X", Var "Y"]
],
_rules = [ _rules = [
RelationRule { RelationRule {
headVariables = [ "X", "Y", "Z" ], headVariables = [ "X", "Y", "Z" ],
@ -86,8 +81,7 @@ spec = do
] ]
} }
] ]
} } ),
),
("parent", parentRelation ) ("parent", parentRelation )
] ]