Merge pull request 'Claude attempts to do a routine rename' (#1) from claude-renaming into main
Reviewed-on: #1
This commit is contained in:
commit
3003a92807
@ -26,9 +26,9 @@ Megaparsec-based parser that converts Datalog text into an AST:
|
||||
- `Statement` - Fact, Rule (with `Head` and body literals), or Query
|
||||
- Entry points: `parseDatalog`, `parseDatalogFile`
|
||||
|
||||
### Evaluation Engine (`src/Datalog/NaiveDatabase.hs`)
|
||||
Naive evaluation database storing relations and rules:
|
||||
- `NaiveDatabase` - Contains `relations` map and `constants` set (Herbrand universe)
|
||||
### Evaluation Engine (`src/Datalog/InMemoryDB.hs`)
|
||||
In-memory database storing relations and rules:
|
||||
- `InMemoryDB` - Contains `relations` map and `constants` set (Herbrand universe)
|
||||
- `Relation` - Name, arity, tuples (facts), and associated rules
|
||||
- `RelationRule` - Head variables and body constraints
|
||||
- Key functions: `withFacts`, `withFactsAndRules` for building databases
|
||||
|
||||
@ -82,16 +82,17 @@ test-suite haskell-exps-test
|
||||
Test.SimpleParserSpec,
|
||||
Test.ArithmeticParserSpec,
|
||||
Test.Datalog.DatalogParserSpec,
|
||||
Test.Datalog.NaiveDatabaseSpec
|
||||
Test.Datalog.InMemoryDBSpec
|
||||
|
||||
library langfeatures
|
||||
default-language: Haskell2010
|
||||
build-depends: base, containers, megaparsec, parser-combinators, text
|
||||
hs-source-dirs: src
|
||||
exposed-modules: Ologs
|
||||
SimpleParser
|
||||
ArithmeticParser
|
||||
Datalog.DatalogParser
|
||||
Datalog.NaiveDatabase
|
||||
Datalog.InMemoryDB
|
||||
Datalog.Rules
|
||||
Datalog.DatalogDB
|
||||
ghc-options: -Wall
|
||||
@ -99,8 +100,8 @@ library langfeatures
|
||||
OverloadedStrings
|
||||
|
||||
executable haskell-experiments
|
||||
default-language: Haskell2010
|
||||
build-depends: base, containers
|
||||
main-is: Main.hs
|
||||
hs-source-dirs: src
|
||||
default-language: Haskell2010
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# NaiveDatabase.hs Summary
|
||||
# InMemoryDB.hs Summary
|
||||
|
||||
This module implements a naive Datalog database with support for facts, rules, and queries.
|
||||
This module implements an in-memory Datalog database with support for facts, rules, and queries.
|
||||
|
||||
## Data Types
|
||||
|
||||
@ -9,7 +9,7 @@ A simple algebraic data type representing values in the database.
|
||||
- `ValueInt Int` - Integer value
|
||||
- `ValueSymbol String` - Symbolic value
|
||||
|
||||
### NaiveDatabase
|
||||
### InMemoryDB
|
||||
The main database structure containing:
|
||||
- `relations :: Map RelationId Relation` - Map of relation names to relations
|
||||
- `constants :: Set Constant` - The Herbrand universe (all constants in the database)
|
||||
@ -46,9 +46,9 @@ Context maintained while processing rules:
|
||||
- `__relation :: Relation` - The relation being defined
|
||||
- `_headVariables :: [RuleElement]` - Variables collected from head and body
|
||||
- `_bodyConstraints :: [BodyConstraint]` - Constraints from rule body
|
||||
- `_db :: NaiveDatabase` - Current database state
|
||||
- `_db :: InMemoryDB` - Current database state
|
||||
|
||||
### NaiveDatabaseException
|
||||
### InMemoryDBException
|
||||
Exception types for error handling:
|
||||
- `CannotParseStatementException` - Failed to parse Datalog text
|
||||
- `NonFactException` - Expected a fact but got another statement type
|
||||
@ -1,10 +1,10 @@
|
||||
digraph NaiveDatabase {
|
||||
digraph InMemoryDB {
|
||||
rankdir=TB;
|
||||
node [shape=record, fontname="Helvetica", fontsize=10];
|
||||
edge [fontname="Helvetica", fontsize=9];
|
||||
|
||||
// Main database
|
||||
NaiveDatabase [label="{NaiveDatabase|relations : Map RelationId Relation\lconstants : Set Constant\l}"];
|
||||
InMemoryDB [label="{InMemoryDB|relations : Map RelationId Relation\lconstants : Set Constant\l}"];
|
||||
|
||||
// Core data types
|
||||
Relation [label="{Relation|_name : Text\l_arity : Int\l_tuples : Set [Constant]\l_rules : [RelationRule]\l}"];
|
||||
@ -18,7 +18,7 @@ digraph NaiveDatabase {
|
||||
|
||||
BodyConstraint [label="{BodyConstraint|_relation : Relation\l_elements : [ConstraintElement]\l}"];
|
||||
|
||||
RuleContext [label="{RuleContext|__relation : Relation\l_headVariables : [RuleElement]\l_bodyConstraints : [BodyConstraint]\l_db : NaiveDatabase\l}"];
|
||||
RuleContext [label="{RuleContext|__relation : Relation\l_headVariables : [RuleElement]\l_bodyConstraints : [BodyConstraint]\l_db : InMemoryDB\l}"];
|
||||
|
||||
// Type aliases (shown as notes)
|
||||
TypeAliases [shape=note, label="Type Aliases\l\lConstant = Term\lRelationId = Text\l"];
|
||||
@ -27,10 +27,10 @@ digraph NaiveDatabase {
|
||||
Value [label="{Value|ValueInt Int\l| ValueSymbol String\l}"];
|
||||
|
||||
// Exception type
|
||||
NaiveDatabaseException [label="{NaiveDatabaseException|CannotParseStatementException\l| NonFactException\l| NonRuleException\l| NonQueryException\l| BadArityException\l| VariableLookupException\l| UnexpectedConstantException\l}"];
|
||||
InMemoryDBException [label="{InMemoryDBException|CannotParseStatementException\l| NonFactException\l| NonRuleException\l| NonQueryException\l| BadArityException\l| VariableLookupException\l| UnexpectedConstantException\l}"];
|
||||
|
||||
// Relationships
|
||||
NaiveDatabase -> Relation [label="contains *", style=solid];
|
||||
InMemoryDB -> Relation [label="contains *", style=solid];
|
||||
Relation -> RelationRule [label="has *", style=solid];
|
||||
RelationRule -> Relation [label="references *", style=dashed];
|
||||
RelationRule -> RuleElement [label="contains *", style=solid];
|
||||
@ -41,14 +41,14 @@ digraph NaiveDatabase {
|
||||
RuleContext -> Relation [label="references", style=dashed];
|
||||
RuleContext -> RuleElement [label="contains *", style=solid];
|
||||
RuleContext -> BodyConstraint [label="contains *", style=solid];
|
||||
RuleContext -> NaiveDatabase [label="references", style=dashed];
|
||||
RuleContext -> InMemoryDB [label="references", style=dashed];
|
||||
|
||||
// Grouping
|
||||
subgraph cluster_core {
|
||||
label="Core Types";
|
||||
style=rounded;
|
||||
color=blue;
|
||||
NaiveDatabase; Relation; RelationRule; RuleElement;
|
||||
InMemoryDB; Relation; RelationRule; RuleElement;
|
||||
}
|
||||
|
||||
subgraph cluster_processing {
|
||||
@ -62,6 +62,6 @@ digraph NaiveDatabase {
|
||||
label="Other";
|
||||
style=rounded;
|
||||
color=gray;
|
||||
Value; NaiveDatabaseException; TypeAliases;
|
||||
Value; InMemoryDBException; TypeAliases;
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,7 @@
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
{-# LANGUAGE BlockArguments #-}
|
||||
|
||||
module Datalog.NaiveDatabase where
|
||||
module Datalog.InMemoryDB where
|
||||
|
||||
import Control.Exception.Base
|
||||
import Data.Map (Map)
|
||||
@ -18,30 +18,30 @@ import Datalog.DatalogParser (Literal (..), Statement (..), parseDatalog)
|
||||
import Datalog.Rules
|
||||
import Datalog.DatalogDB
|
||||
|
||||
data NaiveDatabase = NaiveDatabase
|
||||
data InMemoryDB = InMemoryDB
|
||||
{ relations :: Map RelationId Relation
|
||||
, constants :: Set Constant
|
||||
} deriving (Show, Eq)
|
||||
|
||||
|
||||
instance DatalogDB NaiveDatabase where
|
||||
emptyDB :: NaiveDatabase
|
||||
emptyDB = NaiveDatabase
|
||||
instance DatalogDB InMemoryDB where
|
||||
emptyDB :: InMemoryDB
|
||||
emptyDB = InMemoryDB
|
||||
{ relations = Map.empty
|
||||
, constants = Set.empty -- the Herbrand universe
|
||||
}
|
||||
|
||||
lookupRelation :: NaiveDatabase -> Text -> Maybe Relation
|
||||
lookupRelation :: InMemoryDB -> Text -> Maybe Relation
|
||||
lookupRelation db relationName =
|
||||
Map.lookup relationName $ relations db
|
||||
|
||||
insertRelation :: NaiveDatabase -> Relation -> NaiveDatabase
|
||||
insertRelation :: InMemoryDB -> Relation -> InMemoryDB
|
||||
insertRelation db relation =
|
||||
db {
|
||||
relations = Map.insert (_name relation) relation (relations db)
|
||||
}
|
||||
|
||||
addConstants :: NaiveDatabase -> Set Constant -> NaiveDatabase
|
||||
addConstants :: InMemoryDB -> Set Constant -> InMemoryDB
|
||||
addConstants db newConstants =
|
||||
db {
|
||||
constants = Set.union newConstants (constants db)
|
||||
@ -78,7 +78,7 @@ withFacts =
|
||||
Right otherStatement -> throw $ NonFactException factText otherStatement
|
||||
Left ex -> throw $ CannotParseStatementException factText ex
|
||||
|
||||
withFactsAndRules :: [Text] -> [Text] -> NaiveDatabase
|
||||
withFactsAndRules :: [Text] -> [Text] -> InMemoryDB
|
||||
withFactsAndRules facts = foldr (addRule . extractRule) (withFacts facts)
|
||||
|
||||
query :: forall db . (DatalogDB db) => db -> Text -> Text
|
||||
@ -87,4 +87,3 @@ query db qText =
|
||||
Right (Query texts literals) -> "#NYI"
|
||||
Right otherStatement -> throw $ NonQueryException qText otherStatement
|
||||
Left ex -> throw $ CannotParseStatementException qText ex
|
||||
|
||||
@ -5,7 +5,7 @@ import qualified Test.OlogsSpec as Ologs
|
||||
import qualified Test.SimpleParserSpec as SimpleParserSpec
|
||||
import qualified Test.ArithmeticParserSpec as ArithmeticParserSpec
|
||||
import qualified Test.Datalog.DatalogParserSpec as DatalogParserSpec
|
||||
import qualified Test.Datalog.NaiveDatabaseSpec as NaiveDatabaseSpec
|
||||
import qualified Test.Datalog.InMemoryDBSpec as InMemoryDBSpec
|
||||
|
||||
main :: IO ()
|
||||
main = hspec $ do
|
||||
@ -13,5 +13,5 @@ main = hspec $ do
|
||||
describe "SimpleParser" SimpleParserSpec.spec
|
||||
describe "ArithmeticParser" ArithmeticParserSpec.spec
|
||||
describe "DatalogParser" DatalogParserSpec.spec
|
||||
describe "NaiveDatabase" NaiveDatabaseSpec.spec
|
||||
describe "InMemoryDB" InMemoryDBSpec.spec
|
||||
|
||||
|
||||
@ -12,22 +12,22 @@
|
||||
{-# LANGUAGE NoMonomorphismRestriction #-}
|
||||
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
|
||||
|
||||
module Test.Datalog.NaiveDatabaseSpec where
|
||||
module Test.Datalog.InMemoryDBSpec where
|
||||
|
||||
import Data.Map qualified as Map
|
||||
import Data.Set qualified as Set
|
||||
import Datalog.DatalogParser
|
||||
import Datalog.NaiveDatabase
|
||||
import Datalog.NaiveDatabase qualified as NaiveDatabase
|
||||
import Datalog.InMemoryDB
|
||||
import Datalog.InMemoryDB qualified as InMemoryDB
|
||||
import Test.Hspec
|
||||
import Datalog.DatalogDB
|
||||
|
||||
spec :: Spec
|
||||
spec = do
|
||||
describe "NaiveDatabase operations" do
|
||||
describe "InMemoryDB operations" do
|
||||
it "can ingest facts into relations & a universe" $ do
|
||||
let db =
|
||||
NaiveDatabase.withFacts
|
||||
InMemoryDB.withFacts
|
||||
[ "parent(\"alice\", \"bob\")."
|
||||
, "parent(\"bob\", \"carol\")."
|
||||
]
|
||||
@ -42,7 +42,7 @@ spec = do
|
||||
]
|
||||
it "can ingest facts and rules" do
|
||||
let db =
|
||||
NaiveDatabase.withFactsAndRules
|
||||
InMemoryDB.withFactsAndRules
|
||||
[ "parent(\"alice\", \"bob\")."
|
||||
, "parent(\"bob\", \"carol\")."
|
||||
]
|
||||
@ -105,7 +105,7 @@ spec = do
|
||||
|
||||
it "can ingest facts and rules with constants" do
|
||||
let db =
|
||||
NaiveDatabase.withFactsAndRules
|
||||
InMemoryDB.withFactsAndRules
|
||||
[]
|
||||
["ancestor(X,\"patriarch\") :- ."]
|
||||
ancestorRule =
|
||||
@ -128,7 +128,7 @@ spec = do
|
||||
|
||||
it "can ingest facts and rules with duplicate head entries" do
|
||||
let db =
|
||||
NaiveDatabase.withFactsAndRules
|
||||
InMemoryDB.withFactsAndRules
|
||||
[]
|
||||
["equivalent(Q,Q) :- ."]
|
||||
equivalentRule =
|
||||
@ -151,7 +151,7 @@ spec = do
|
||||
|
||||
it "can ingest facts and rules with duplicate head entries" do
|
||||
let db =
|
||||
NaiveDatabase.withFactsAndRules
|
||||
InMemoryDB.withFactsAndRules
|
||||
[]
|
||||
["equivalent(Q,Q) :- ."]
|
||||
rule1 =
|
||||
@ -175,7 +175,7 @@ spec = do
|
||||
|
||||
it "can ingest a theory of equivalence relations" do
|
||||
let db =
|
||||
NaiveDatabase.withFactsAndRules
|
||||
InMemoryDB.withFactsAndRules
|
||||
[]
|
||||
[ "equivalent(Q,Q) :- ."
|
||||
, "equivalent(R,Q) :- equivalent(Q,R)."
|
||||
@ -233,8 +233,8 @@ spec = do
|
||||
`shouldBe` Set.empty
|
||||
|
||||
it "can do basic queries" do
|
||||
let db :: NaiveDatabase =
|
||||
NaiveDatabase.withFacts
|
||||
let db :: InMemoryDB =
|
||||
InMemoryDB.withFacts
|
||||
[ "parent(\"alice\", \"bob\")."
|
||||
, "parent(\"bob\", \"carol\")."
|
||||
]
|
||||
Loading…
x
Reference in New Issue
Block a user