{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
#if (__GLASGOW_HASKELL__ >= 802)
{-# LANGUAGE DerivingStrategies #-}
#endif
module Swish.Rule
( Expression(..), Formula(..), Rule(..), RuleMap
, nullScope, nullSN, nullFormula, nullRule
, fwdCheckInference, bwdCheckInference
, showsFormula, showsFormulae, showsWidth
)
where
import Swish.Namespace (Namespace, ScopedName)
import Swish.Namespace (makeNamespace, makeNSScopedName)
import Swish.QName (LName)
import Data.Maybe (fromJust)
import Data.String.ShowLines (ShowLines(..))
import Network.URI (URI, parseURI)
import qualified Data.Map as M
class (Eq ex) => Expression ex where
isValid :: ex -> Bool
data Formula ex = Formula
{ forall ex. Formula ex -> ScopedName
formName :: ScopedName
, forall ex. Formula ex -> ex
formExpr :: ex
} deriving
#if (__GLASGOW_HASKELL__ >= 802)
stock
#endif
Int -> Formula ex -> ShowS
[Formula ex] -> ShowS
Formula ex -> String
(Int -> Formula ex -> ShowS)
-> (Formula ex -> String)
-> ([Formula ex] -> ShowS)
-> Show (Formula ex)
forall ex. Show ex => Int -> Formula ex -> ShowS
forall ex. Show ex => [Formula ex] -> ShowS
forall ex. Show ex => Formula ex -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall ex. Show ex => Int -> Formula ex -> ShowS
showsPrec :: Int -> Formula ex -> ShowS
$cshow :: forall ex. Show ex => Formula ex -> String
show :: Formula ex -> String
$cshowList :: forall ex. Show ex => [Formula ex] -> ShowS
showList :: [Formula ex] -> ShowS
Show
instance Eq (Formula ex) where
Formula ex
f1 == :: Formula ex -> Formula ex -> Bool
== Formula ex
f2 = Formula ex -> ScopedName
forall ex. Formula ex -> ScopedName
formName Formula ex
f1 ScopedName -> ScopedName -> Bool
forall a. Eq a => a -> a -> Bool
== Formula ex -> ScopedName
forall ex. Formula ex -> ScopedName
formName Formula ex
f2
instance Ord (Formula ex) where
Formula ex
f1 <= :: Formula ex -> Formula ex -> Bool
<= Formula ex
f2 = Formula ex -> ScopedName
forall ex. Formula ex -> ScopedName
formName Formula ex
f1 ScopedName -> ScopedName -> Bool
forall a. Ord a => a -> a -> Bool
<= Formula ex -> ScopedName
forall ex. Formula ex -> ScopedName
formName Formula ex
f2
nullScope :: Namespace
nullScope :: Namespace
nullScope = Maybe Text -> URI -> Namespace
makeNamespace (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"null") URI
nullScopeURI
nullSN ::
LName
-> ScopedName
nullSN :: LName -> ScopedName
nullSN = Namespace -> LName -> ScopedName
makeNSScopedName Namespace
nullScope
tU :: String -> URI
tU :: String -> URI
tU = Maybe URI -> URI
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe URI -> URI) -> (String -> Maybe URI) -> String -> URI
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe URI
parseURI
nullScopeURI :: URI
nullScopeURI :: URI
nullScopeURI = String -> URI
tU String
"http://id.ninebynine.org/2003/Ruleset/null"
nullFormula :: Formula ex
nullFormula :: forall ex. Formula ex
nullFormula = Formula
{ formName :: ScopedName
formName = Namespace -> LName -> ScopedName
makeNSScopedName Namespace
nullScope LName
"nullFormula"
, formExpr :: ex
formExpr = String -> ex
forall a. HasCallStack => String -> a
error String
"Null formula"
}
showsFormulae ::
(ShowLines ex)
=> String
-> [Formula ex]
-> String
-> ShowS
showsFormulae :: forall ex.
ShowLines ex =>
String -> [Formula ex] -> String -> ShowS
showsFormulae String
_ [] String
_ = ShowS
forall a. a -> a
id
showsFormulae String
newline [Formula ex
f] String
after = String -> Formula ex -> ShowS
forall ex. ShowLines ex => String -> Formula ex -> ShowS
showsFormula String
newline Formula ex
f ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
after
showsFormulae String
newline (Formula ex
f:[Formula ex]
fs) String
after = String -> Formula ex -> ShowS
forall ex. ShowLines ex => String -> Formula ex -> ShowS
showsFormula String
newline Formula ex
f ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ShowS
showString String
newline ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> [Formula ex] -> String -> ShowS
forall ex.
ShowLines ex =>
String -> [Formula ex] -> String -> ShowS
showsFormulae String
newline [Formula ex]
fs String
after
showsFormula ::
(ShowLines ex)
=> String
-> Formula ex
-> ShowS
showsFormula :: forall ex. ShowLines ex => String -> Formula ex -> ShowS
showsFormula String
newline Formula ex
f =
Int -> String -> ShowS
showsWidth Int
16 (String
"[" String -> ShowS
forall a. [a] -> [a] -> [a]
++ ScopedName -> String
forall a. Show a => a -> String
show (Formula ex -> ScopedName
forall ex. Formula ex -> ScopedName
formName Formula ex
f) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"] ") ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> ex -> ShowS
forall sh. ShowLines sh => String -> sh -> ShowS
showls (String
newline String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
16 Char
' ') (Formula ex -> ex
forall ex. Formula ex -> ex
formExpr Formula ex
f)
data Rule ex = Rule
{
forall ex. Rule ex -> ScopedName
ruleName :: ScopedName,
forall ex. Rule ex -> [ex] -> [ex]
fwdApply :: [ex] -> [ex],
forall ex. Rule ex -> ex -> [[ex]]
bwdApply :: ex -> [[ex]],
forall ex. Rule ex -> [ex] -> ex -> Bool
checkInference :: [ex] -> ex -> Bool
}
instance Eq (Rule ex) where
Rule ex
r1 == :: Rule ex -> Rule ex -> Bool
== Rule ex
r2 = Rule ex -> ScopedName
forall ex. Rule ex -> ScopedName
ruleName Rule ex
r1 ScopedName -> ScopedName -> Bool
forall a. Eq a => a -> a -> Bool
== Rule ex -> ScopedName
forall ex. Rule ex -> ScopedName
ruleName Rule ex
r2
instance Ord (Rule ex) where
Rule ex
r1 <= :: Rule ex -> Rule ex -> Bool
<= Rule ex
r2 = Rule ex -> ScopedName
forall ex. Rule ex -> ScopedName
ruleName Rule ex
r1 ScopedName -> ScopedName -> Bool
forall a. Ord a => a -> a -> Bool
<= Rule ex -> ScopedName
forall ex. Rule ex -> ScopedName
ruleName Rule ex
r2
instance Show (Rule ex) where
show :: Rule ex -> String
show Rule ex
rl = String
"Rule " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ScopedName -> String
forall a. Show a => a -> String
show (Rule ex -> ScopedName
forall ex. Rule ex -> ScopedName
ruleName Rule ex
rl)
type RuleMap ex = M.Map ScopedName (Rule ex)
fwdCheckInference ::
(Eq ex)
=> Rule ex
-> [ex]
-> ex
-> Bool
fwdCheckInference :: forall ex. Eq ex => Rule ex -> [ex] -> ex -> Bool
fwdCheckInference Rule ex
rule [ex]
ante ex
cons =
ex
cons ex -> [ex] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Rule ex -> [ex] -> [ex]
forall ex. Rule ex -> [ex] -> [ex]
fwdApply Rule ex
rule [ex]
ante
bwdCheckInference ::
(Eq ex)
=> Rule ex
-> [ex]
-> ex
-> Bool
bwdCheckInference :: forall ex. Eq ex => Rule ex -> [ex] -> ex -> Bool
bwdCheckInference Rule ex
rule [ex]
ante ex
cons = ([ex] -> Bool) -> [[ex]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any [ex] -> Bool
checkAnts (Rule ex -> ex -> [[ex]]
forall ex. Rule ex -> ex -> [[ex]]
bwdApply Rule ex
rule ex
cons)
where
checkAnts :: [ex] -> Bool
checkAnts = (ex -> Bool) -> [ex] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (ex -> [ex] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ex]
ante)
nullRule :: Rule ex
nullRule :: forall ex. Rule ex
nullRule = Rule
{ ruleName :: ScopedName
ruleName = Namespace -> LName -> ScopedName
makeNSScopedName Namespace
nullScope LName
"nullRule"
, fwdApply :: [ex] -> [ex]
fwdApply = [ex] -> [ex] -> [ex]
forall a b. a -> b -> a
const []
, bwdApply :: ex -> [[ex]]
bwdApply = [[ex]] -> ex -> [[ex]]
forall a b. a -> b -> a
const []
, checkInference :: [ex] -> ex -> Bool
checkInference = \ [ex]
_ ex
_ -> Bool
False
}
showsWidth :: Int -> String -> ShowS
showsWidth :: Int -> String -> ShowS
showsWidth Int
wid String
str String
more = String
str String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
pad Char
' ' String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
more
where
pad :: Int
pad = Int
wid Int -> Int -> Int
forall a. Num a => a -> a -> a
- String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str