106 lines
3.4 KiB
Haskell

{-# 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 #-}
{-# LANGUAGE ImportQualifiedPost #-}
module Test.Datalog.NaiveDatabaseSpec where
import Test.Hspec
import Datalog.NaiveDatabase
import qualified Datalog.NaiveDatabase as NaiveDatabase
import Data.Set qualified as Set
import Datalog.DatalogParser
import qualified Data.Map as Map
spec :: Spec
spec = do
describe "dummy test" $ do
it "..." $ do
1 `shouldBe` (1 :: Int)
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",
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 [
("ancestor",
Relation {
_arity = 2,
_tuples = Set.fromList [
[Var "X", Var "Y"]
],
_rules = [
RelationRule {
headVariables = [
RuleElementVariable "X",
RuleElementVariable "Y",
RuleElementVariable "Z"
],
body = [
(
Relation {
_arity = 2,
_tuples = Set.fromList [
[Var "X",Var "Z" ]
],
_rules = []
}, [
RuleElementVariable "X",
RuleElementVariable "Z"
]
),(
Relation {
_arity = 2,
_tuples = Set.fromList [
[Var "Z",Var "Y"]
],
_rules = []
},[
RuleElementVariable "Z",
RuleElementVariable "Y"
]
)
]
}
]
}
),
("parent",
Relation {
_arity = 2,
_tuples = Set.fromList [
[Var "X",Var "Z"]
],
_rules = []
}
)
]
it "can do basic queries" $ do
let db = NaiveDatabase.withFacts
[ "parent(\"alice\", \"bob\")."
, "parent(\"bob\", \"carol\")." ]
query db "?- parent(alice,X)." `shouldBe` "#NYI" -- ideally, 'bob'