    --------------------------------------------------------------------------------
    --  See end of this file for licence information.
    --------------------------------------------------------------------------------
    -- |
    --  Module      :  Rules
    --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012, 2022 Douglas Burke
    --  License     :  GPL V2
    --
    --  Maintainer  :  Douglas Burke
    --  Stability   :  experimental
    --  Portability :  H98
    --
    --  This module collects references and provides access to all of the
    --  rulesets, variable binding modifiers and variable binding filters
    --  built in to Swish.
    --
    --------------------------------------------------------------------------------

    module Swish.RDF.BuiltIn.Rules
        ( findRDFOpenVarBindingModifier
        , rdfRulesetMap
        , allRulesets, allDatatypeRulesets
        )
    where

    import Swish.Datatype (typeRules, typeMkModifiers)
    import Swish.Namespace (ScopedName)
    import Swish.Ruleset (getRulesetNamespace)
    import Swish.VarBinding (openVbmName, nullVarBindingModify, makeVarFilterModify, varFilterEQ, varFilterNE)

    import Swish.RDF.BuiltIn.Datatypes (allDatatypes)
    import Swish.RDF.Ruleset (RDFRuleset, RDFRulesetMap)
    import Swish.RDF.ProofContext (rulesetRDF, rulesetRDFS, rulesetRDFD)

    import Swish.RDF.VarBinding
        ( RDFOpenVarBindingModify
        , rdfVarBindingUriRef, rdfVarBindingBlank
        , rdfVarBindingLiteral
        , rdfVarBindingUntypedLiteral, rdfVarBindingTypedLiteral
        , rdfVarBindingXMLLiteral, rdfVarBindingDatatyped
        , rdfVarBindingMemberProp
        )

    import qualified Data.Map as M

    ------------------------------------------------------------
    --  Declare variable binding filters list
    ------------------------------------------------------------

    -- |List of rdfOpenVarBindingModify values for predefined filters
    --
    rdfVarBindingFilters :: [RDFOpenVarBindingModify]
    rdfVarBindingFilters :: [RDFOpenVarBindingModify]
    rdfVarBindingFilters =
        [ (RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter1 RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    rdfVarBindingUriRef
        , (RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter1 RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    rdfVarBindingBlank
        , (RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter1 RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    rdfVarBindingLiteral
        , (RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter1 RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    rdfVarBindingUntypedLiteral
        , (RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter1 RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    rdfVarBindingTypedLiteral
        , (RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter1 RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    rdfVarBindingXMLLiteral
        , (RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter1 RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    rdfVarBindingMemberProp
        , (RDFLabel -> RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter2 RDFLabel -> RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    rdfVarBindingDatatyped
        -- , filterN nullVarBindingModify
        , (RDFLabel -> RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter2 RDFLabel -> RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    forall b a. Eq b => a -> a -> VarBindingFilter a b
    varFilterEQ
        , (RDFLabel -> RDFLabel -> VarBindingFilter RDFLabel RDFLabel)
    -> RDFOpenVarBindingModify
    forall {t} {a} {b}.
    (t -> t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter2 RDFLabel -> RDFLabel -> VarBindingFilter RDFLabel RDFLabel
    forall b a. Eq b => a -> a -> VarBindingFilter a b
    varFilterNE
        ]
        where
          -- Swish.RDF.VarBinding.openVbmName seems to require that the label
          -- list not be evaluated which means that we can not replace these
          -- statements by ones like
          --
          --    filter1 f (lb:_) = makeVarFilterModift $ f lb
          --
          filter1 :: (t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter1 t -> VarBindingFilter a b
    f [t]
    lbs = VarBindingFilter a b -> VarBindingModify a b
    forall a b. VarBindingFilter a b -> VarBindingModify a b
    makeVarFilterModify (VarBindingFilter a b -> VarBindingModify a b)
    -> VarBindingFilter a b -> VarBindingModify a b
    forall a b. (a -> b) -> a -> b
    $ t -> VarBindingFilter a b
    f ([t] -> t
    forall a. HasCallStack => [a] -> a
    head [t]
    lbs)
          filter2 :: (t -> t -> VarBindingFilter a b) -> [t] -> VarBindingModify a b
    filter2 t -> t -> VarBindingFilter a b
    f [t]
    lbs = VarBindingFilter a b -> VarBindingModify a b
    forall a b. VarBindingFilter a b -> VarBindingModify a b
    makeVarFilterModify (VarBindingFilter a b -> VarBindingModify a b)
    -> VarBindingFilter a b -> VarBindingModify a b
    forall a b. (a -> b) -> a -> b
    $ t -> t -> VarBindingFilter a b
    f ([t] -> t
    forall a. HasCallStack => [a] -> a
    head [t]
    lbs) ([t]
    lbs [t] -> Int -> t
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    1)
          -- filterN f lbs = makeVarFilterModify $ f ...

    ------------------------------------------------------------
    --  Declare variable binding modifiers map
    ------------------------------------------------------------

    rdfVarBindingModifiers :: [RDFOpenVarBindingModify]
    rdfVarBindingModifiers :: [RDFOpenVarBindingModify]
    rdfVarBindingModifiers =
        [ RDFOpenVarBindingModify
    forall a b. OpenVarBindingModify a b
    nullVarBindingModify
        ]

    ------------------------------------------------------------
    --  Find a named built-in OpenVarBindingModifier
    ------------------------------------------------------------

    allOpenVarBindingModify :: [RDFOpenVarBindingModify]
    allOpenVarBindingModify :: [RDFOpenVarBindingModify]
    allOpenVarBindingModify =
        [RDFOpenVarBindingModify]
    rdfVarBindingFilters    [RDFOpenVarBindingModify]
    -> [RDFOpenVarBindingModify] -> [RDFOpenVarBindingModify]
    forall a. [a] -> [a] -> [a]
    ++
        [RDFOpenVarBindingModify]
    rdfVarBindingModifiers  [RDFOpenVarBindingModify]
    -> [RDFOpenVarBindingModify] -> [RDFOpenVarBindingModify]
    forall a. [a] -> [a] -> [a]
    ++
        [RDFOpenVarBindingModify]
    dtsVarBindingModifiers

    dtsVarBindingModifiers :: [RDFOpenVarBindingModify]
    -- dtsVarBindingModifiers = concatMap dtVarBindingModifiers allDatatypes
    dtsVarBindingModifiers :: [RDFOpenVarBindingModify]
    dtsVarBindingModifiers = (Datatype RDFGraph RDFLabel RDFLabel -> [RDFOpenVarBindingModify])
    -> [Datatype RDFGraph RDFLabel RDFLabel]
    -> [RDFOpenVarBindingModify]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap Datatype RDFGraph RDFLabel RDFLabel -> [RDFOpenVarBindingModify]
    forall ex lb vn. Datatype ex lb vn -> [OpenVarBindingModify lb vn]
    typeMkModifiers [Datatype RDFGraph RDFLabel RDFLabel]
    allDatatypes

    {-
    dtVarBindingModifiers dtval =
        map (makeRdfDtOpenVarBindingModify dtval) (tvalMod dtval)
    -}

    -- | Find the named open variable binding modifier.
    findRDFOpenVarBindingModifier :: ScopedName -> Maybe RDFOpenVarBindingModify
    findRDFOpenVarBindingModifier :: ScopedName -> Maybe RDFOpenVarBindingModify
    findRDFOpenVarBindingModifier ScopedName
    nam =
        ScopedName
    -> Map ScopedName RDFOpenVarBindingModify
    -> Maybe RDFOpenVarBindingModify
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup ScopedName
    nam (Map ScopedName RDFOpenVarBindingModify
     -> Maybe RDFOpenVarBindingModify)
    -> Map ScopedName RDFOpenVarBindingModify
    -> Maybe RDFOpenVarBindingModify
    forall a b. (a -> b) -> a -> b
    $ [(ScopedName, RDFOpenVarBindingModify)]
    -> Map ScopedName RDFOpenVarBindingModify
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([(ScopedName, RDFOpenVarBindingModify)]
     -> Map ScopedName RDFOpenVarBindingModify)
    -> [(ScopedName, RDFOpenVarBindingModify)]
    -> Map ScopedName RDFOpenVarBindingModify
    forall a b. (a -> b) -> a -> b
    $ (RDFOpenVarBindingModify -> (ScopedName, RDFOpenVarBindingModify))
    -> [RDFOpenVarBindingModify]
    -> [(ScopedName, RDFOpenVarBindingModify)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\RDFOpenVarBindingModify
    ovbm -> (RDFOpenVarBindingModify -> ScopedName
    forall lb vn. OpenVarBindingModify lb vn -> ScopedName
    openVbmName RDFOpenVarBindingModify
    ovbm, RDFOpenVarBindingModify
    ovbm))
                                    [RDFOpenVarBindingModify]
    allOpenVarBindingModify

    ------------------------------------------------------------
    --  Lookup map for built-in rulesets
    ------------------------------------------------------------

    -- | A 'LookupMap' of 'allRulesets'.
    rdfRulesetMap :: RDFRulesetMap
    rdfRulesetMap :: RDFRulesetMap
    rdfRulesetMap = [(Namespace, Ruleset RDFGraph)] -> RDFRulesetMap
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([(Namespace, Ruleset RDFGraph)] -> RDFRulesetMap)
    -> [(Namespace, Ruleset RDFGraph)] -> RDFRulesetMap
    forall a b. (a -> b) -> a -> b
    $ (Ruleset RDFGraph -> (Namespace, Ruleset RDFGraph))
    -> [Ruleset RDFGraph] -> [(Namespace, Ruleset RDFGraph)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Ruleset RDFGraph
    r -> (Ruleset RDFGraph -> Namespace
    forall ex. Ruleset ex -> Namespace
    getRulesetNamespace Ruleset RDFGraph
    r, Ruleset RDFGraph
    r)) [Ruleset RDFGraph]
    allRulesets

    -- | All the rule sets known to Swish.
    allRulesets :: [RDFRuleset]
    allRulesets :: [Ruleset RDFGraph]
    allRulesets =
        [ Ruleset RDFGraph
    rulesetRDF
        , Ruleset RDFGraph
    rulesetRDFS
        , Ruleset RDFGraph
    rulesetRDFD
        ]
        [Ruleset RDFGraph] -> [Ruleset RDFGraph] -> [Ruleset RDFGraph]
    forall a. [a] -> [a] -> [a]
    ++ [Ruleset RDFGraph]
    allDatatypeRulesets

    -- | The data type rule sets known to Swish.
    allDatatypeRulesets :: [RDFRuleset]
    allDatatypeRulesets :: [Ruleset RDFGraph]
    allDatatypeRulesets = (Datatype RDFGraph RDFLabel RDFLabel -> Ruleset RDFGraph)
    -> [Datatype RDFGraph RDFLabel RDFLabel] -> [Ruleset RDFGraph]
    forall a b. (a -> b) -> [a] -> [b]
    map Datatype RDFGraph RDFLabel RDFLabel -> Ruleset RDFGraph
    forall ex lb vn. Datatype ex lb vn -> Ruleset ex
    typeRules [Datatype RDFGraph RDFLabel RDFLabel]
    allDatatypes

    --------------------------------------------------------------------------------
    --
    --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
    --    2011, 2012, 2022 Douglas Burke
    --  All rights reserved.
    --
    --  This file is part of Swish.
    --
    --  Swish is free software; you can redistribute it and/or modify
    --  it under the terms of the GNU General Public License as published by
    --  the Free Software Foundation; either version 2 of the License, or
    --  (at your option) any later version.
    --
    --  Swish is distributed in the hope that it will be useful,
    --  but WITHOUT ANY WARRANTY; without even the implied warranty of
    --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    --  GNU General Public License for more details.
    --
    --  You should have received a copy of the GNU General Public License
    --  along with Swish; if not, write to:
    --    The Free Software Foundation, Inc.,
    --    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    --
    --------------------------------------------------------------------------------