87 lines
2.9 KiB
Haskell
Raw Normal View History

2026-01-21 11:24:30 +00:00
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# HLINT ignore "Use const" #-}
{-# HLINT ignore "Unused LANGUAGE pragma" #-}
{-# HLINT ignore "Avoid lambda" #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoFieldSelectors #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
{-# LANGUAGE TypeApplications #-}
2026-01-22 14:25:09 +00:00
{-# LANGUAGE ImportQualifiedPost #-}
2026-01-21 11:24:30 +00:00
module Test.Datalog.NaiveDatabaseSpec where
import Test.Hspec
import Datalog.NaiveDatabase
2026-01-21 17:11:13 +00:00
import qualified Datalog.NaiveDatabase as NaiveDatabase
2026-01-22 14:25:09 +00:00
import Data.Set qualified as Set
import Datalog.DatalogParser
import qualified Data.Map as Map
2026-01-21 11:24:30 +00:00
spec :: Spec
spec = do
2026-01-26 18:28:15 +00:00
describe "NaiveDatabase operations" $ do
2026-01-21 11:24:30 +00:00
it "..." $ do
1 `shouldBe` (1 :: Int)
2026-01-22 14:25:09 +00:00
it "can ingest facts into relations & a universe" $ do
let db = NaiveDatabase.withFacts
[ "parent(\"alice\", \"bob\")."
, "parent(\"bob\", \"carol\")." ]
constants db `shouldBe`
(Set.fromList $ Sym <$> ["alice", "bob", "carol"])
relations db `shouldBe`
Map.fromList [
("parent",
2026-01-26 18:28:15 +00:00
Relation "parent" 2 (Set.fromList (map (Sym <$>) [["alice", "bob"], ["bob", "carol"]])) [] )
2026-01-22 14:25:09 +00:00
]
2026-01-22 17:33:49 +00:00
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)." ]
2026-01-26 18:28:15 +00:00
constants db `shouldBe`
(Set.fromList $ Sym <$> ["alice", "bob", "carol"])
2026-01-26 12:25:44 +00:00
let parentRelation = Relation {
_name = "parent",
_arity = 2,
2026-01-26 18:28:15 +00:00
_tuples = Set.fromList $
map (Sym <$>) [["alice", "bob"], ["bob", "carol"]],
2026-01-26 12:25:44 +00:00
_rules = []
}
2026-01-27 12:41:23 +00:00
let ancestorRule = RelationRule {
headVariables = [ "X", "Y", "Z" ],
bodyElements = [
RuleBodyElement {
_subRelationName = "parent",
_ruleElements = [
RuleElementVariable "X", RuleElementVariable "Z"
]
},
RuleBodyElement {
_subRelationName = "ancestor",
_ruleElements = [
RuleElementVariable "Z",RuleElementVariable "Y"
]
}
]
}
2026-01-26 12:25:44 +00:00
let ancestorRelation = Relation {
2026-01-27 12:41:23 +00:00
_arity = 2,
_name = "ancestor",
_tuples = Set.empty,
_rules = [ ancestorRule ]
}
2026-01-22 17:33:49 +00:00
relations db `shouldBe`
Map.fromList [
2026-01-27 12:41:23 +00:00
("ancestor", ancestorRelation),
("parent", parentRelation )
]
2026-01-22 14:25:09 +00:00
it "can do basic queries" $ do
2026-01-21 18:01:06 +00:00
let db = NaiveDatabase.withFacts
[ "parent(\"alice\", \"bob\")."
, "parent(\"bob\", \"carol\")." ]
2026-01-22 14:25:09 +00:00
query db "?- parent(alice,X)." `shouldBe` "#NYI" -- ideally, 'bob'