delinting with an h
This commit is contained in:
parent
fb2699624f
commit
5c0cc77221
@ -82,8 +82,8 @@ expr = factor `chainl1` addOrSub
|
|||||||
-- └───────────────────────────────┘
|
-- └───────────────────────────────┘
|
||||||
|
|
||||||
parseExpr :: Text -> Either (ParseErrorBundle Text Void) Expr
|
parseExpr :: Text -> Either (ParseErrorBundle Text Void) Expr
|
||||||
parseExpr input =
|
parseExpr =
|
||||||
parse (sc *> expr <* eof) "<input>" input
|
parse (sc *> expr <* eof) "<input>"
|
||||||
|
|
||||||
-- ┌───────────────────────────────┐
|
-- ┌───────────────────────────────┐
|
||||||
-- │ Helpful chainl1 alias │
|
-- │ Helpful chainl1 alias │
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE TypeApplications #-}
|
|
||||||
|
|
||||||
module Datalog.DatalogParser where
|
module Datalog.DatalogParser where
|
||||||
|
|
||||||
@ -10,6 +9,7 @@ import Text.Megaparsec
|
|||||||
import Text.Megaparsec.Char
|
import Text.Megaparsec.Char
|
||||||
import qualified Text.Megaparsec.Char.Lexer as L
|
import qualified Text.Megaparsec.Char.Lexer as L
|
||||||
import Control.Monad (void)
|
import Control.Monad (void)
|
||||||
|
import Data.Functor (($>))
|
||||||
|
|
||||||
-- ┌───────────────────────────────────────────────┐
|
-- ┌───────────────────────────────────────────────┐
|
||||||
-- │ Basic types │
|
-- │ Basic types │
|
||||||
@ -29,8 +29,8 @@ data Literal = Literal
|
|||||||
, arguments :: [Term]
|
, arguments :: [Term]
|
||||||
} deriving (Show, Eq)
|
} deriving (Show, Eq)
|
||||||
|
|
||||||
data Head
|
newtype Head
|
||||||
= HeadSingle Literal -- only case
|
= HeadSingle Literal
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
-- data Head
|
-- data Head
|
||||||
@ -64,10 +64,11 @@ parens :: Parser a -> Parser a
|
|||||||
parens = between (symbol "(") (symbol ")")
|
parens = between (symbol "(") (symbol ")")
|
||||||
|
|
||||||
comma :: Parser ()
|
comma :: Parser ()
|
||||||
comma = () <$ symbol ","
|
comma = void $ symbol ","
|
||||||
|
-- () <$ symbol ","
|
||||||
|
|
||||||
dot :: Parser ()
|
dot :: Parser ()
|
||||||
dot = () <$ symbol "."
|
dot = void $ symbol "."
|
||||||
|
|
||||||
arrow :: Parser ()
|
arrow :: Parser ()
|
||||||
arrow = void $ symbol ":-" <|> symbol "→" <|> symbol "->"
|
arrow = void $ symbol ":-" <|> symbol "→" <|> symbol "->"
|
||||||
@ -98,14 +99,17 @@ term = choice
|
|||||||
-- │ Literal / atom │
|
-- │ Literal / atom │
|
||||||
-- └───────────────────────────────────────────────┘
|
-- └───────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
literal :: Parser Literal
|
literal :: Parser Literal
|
||||||
literal = do
|
literal = do
|
||||||
neg <- (symbol "not" *> sc *> pure False)
|
neg <- prefixedBy "not"
|
||||||
<|> (symbol "!" *> sc *> pure False)
|
<|> prefixedBy "!"
|
||||||
<|> pure True
|
<|> pure True
|
||||||
name <- identifier
|
name <- identifier
|
||||||
args <- parens (term `sepBy` comma) <|> pure []
|
args <- parens (term `sepBy` comma) <|> pure []
|
||||||
pure $ Literal neg name args
|
pure $ Literal neg name args where
|
||||||
|
prefixedBy op = (symbol op *> sc) $> False
|
||||||
|
|
||||||
-- ┌───────────────────────────────────────────────┐
|
-- ┌───────────────────────────────────────────────┐
|
||||||
-- │ Head │
|
-- │ Head │
|
||||||
|
|||||||
@ -18,10 +18,6 @@ import Data.Void
|
|||||||
import Datalog.DatalogParser (Head (HeadSingle), Literal (..), Statement (..), Term (..), parseDatalog)
|
import Datalog.DatalogParser (Head (HeadSingle), Literal (..), Statement (..), Term (..), parseDatalog)
|
||||||
import Text.Megaparsec (ParseErrorBundle)
|
import Text.Megaparsec (ParseErrorBundle)
|
||||||
|
|
||||||
data Value
|
|
||||||
= ValueInt Int
|
|
||||||
| ValueSymbol String
|
|
||||||
|
|
||||||
data NaiveDatabase = NaiveDatabase
|
data NaiveDatabase = NaiveDatabase
|
||||||
{ relations :: Map RelationId Relation
|
{ relations :: Map RelationId Relation
|
||||||
, constants :: Set Constant
|
, constants :: Set Constant
|
||||||
@ -63,9 +59,19 @@ emptyDB =
|
|||||||
, constants = Set.empty -- the Herbrand universe
|
, constants = Set.empty -- the Herbrand universe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lookupRelation :: RelationId -> Map RelationId Relation -> Int -> Set [Term] -> Relation
|
||||||
|
lookupRelation relationName relationMap newArity tuples =
|
||||||
|
case Map.lookup relationName relationMap of
|
||||||
|
Nothing -> Relation relationName newArity tuples []
|
||||||
|
Just relation ->
|
||||||
|
if _arity relation == newArity then
|
||||||
|
let newTuples = Set.union tuples $ _tuples relation
|
||||||
|
in Relation relationName newArity newTuples []
|
||||||
|
else throw $ BadArityException relationName newArity
|
||||||
|
|
||||||
withFacts :: [Text] -> NaiveDatabase
|
withFacts :: [Text] -> NaiveDatabase
|
||||||
withFacts facts =
|
withFacts =
|
||||||
foldr addFact emptyDB (extractFact <$> facts)
|
foldr (addFact . extractFact) emptyDB
|
||||||
where
|
where
|
||||||
extractFact :: Text -> Literal
|
extractFact :: Text -> Literal
|
||||||
extractFact factText =
|
extractFact factText =
|
||||||
@ -82,16 +88,6 @@ withFacts facts =
|
|||||||
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 -> Set [Term] -> Relation
|
|
||||||
lookupRelation relationName relationMap newArity tuples =
|
|
||||||
case Map.lookup relationName relationMap of
|
|
||||||
Nothing -> Relation relationName newArity tuples []
|
|
||||||
Just relation ->
|
|
||||||
if _arity relation == newArity then
|
|
||||||
let newTuples = Set.union tuples $ _tuples relation
|
|
||||||
in Relation relationName newArity newTuples []
|
|
||||||
else throw $ BadArityException relationName newArity
|
|
||||||
|
|
||||||
data BodyConstraint = BodyConstraint
|
data BodyConstraint = BodyConstraint
|
||||||
{ _subRelation :: Relation
|
{ _subRelation :: Relation
|
||||||
, _elements :: [RuleElement]
|
, _elements :: [RuleElement]
|
||||||
@ -167,7 +163,7 @@ withFactsAndRules facts = foldr (addRule . extractRule) (withFacts facts)
|
|||||||
|
|
||||||
lookupVariable :: Text -> [Text] -> Int
|
lookupVariable :: Text -> [Text] -> Int
|
||||||
lookupVariable varName variableNames =
|
lookupVariable varName variableNames =
|
||||||
case (elemIndex varName) variableNames of
|
case elemIndex varName variableNames of
|
||||||
Just index -> index
|
Just index -> index
|
||||||
Nothing -> throw $ VariableLookupException varName variableNames
|
Nothing -> throw $ VariableLookupException varName variableNames
|
||||||
|
|
||||||
@ -183,24 +179,24 @@ withFactsAndRules facts = foldr (addRule . extractRule) (withFacts facts)
|
|||||||
context' = foldr digestBody context body
|
context' = foldr digestBody context body
|
||||||
db' = _db context'
|
db' = _db context'
|
||||||
relationMap = relations db'
|
relationMap = relations db'
|
||||||
newRule =
|
|
||||||
RelationRule
|
|
||||||
{ headVariables = _variableNames context'
|
|
||||||
, bodyElements = toRuleBodyElement <$> _bodyConstraints context'
|
|
||||||
} where
|
|
||||||
toRuleBodyElement :: BodyConstraint -> RuleBodyElement
|
|
||||||
toRuleBodyElement (BodyConstraint subRelation elements) =
|
|
||||||
RuleBodyElement {
|
|
||||||
_subRelationId = _name subRelation
|
|
||||||
, _ruleElements = elements
|
|
||||||
}
|
|
||||||
relation' =
|
relation' =
|
||||||
Relation
|
Relation
|
||||||
{ _name = _name relation
|
{ _name = _name relation
|
||||||
, _arity = newArity
|
, _arity = newArity
|
||||||
, _tuples = _tuples relation
|
, _tuples = _tuples relation
|
||||||
, _rules = newRule : _rules relation
|
, _rules = newRule : _rules relation
|
||||||
}
|
} where
|
||||||
|
newRule =
|
||||||
|
RelationRule
|
||||||
|
{ headVariables = _variableNames context'
|
||||||
|
, bodyElements = toRuleBodyElement <$> _bodyConstraints context'
|
||||||
|
}
|
||||||
|
toRuleBodyElement :: BodyConstraint -> RuleBodyElement
|
||||||
|
toRuleBodyElement (BodyConstraint subRelation elements) =
|
||||||
|
RuleBodyElement {
|
||||||
|
_subRelationId = _name subRelation
|
||||||
|
, _ruleElements = elements
|
||||||
|
}
|
||||||
relationMap' = Map.insert relationName relation' relationMap
|
relationMap' = Map.insert relationName relation' relationMap
|
||||||
constants' = constants db'
|
constants' = constants db'
|
||||||
extractVariableNames :: [Term] -> [Text]
|
extractVariableNames :: [Term] -> [Text]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user