    --------------------------------------------------------------------------------
    --  See end of this file for licence information.
    --------------------------------------------------------------------------------
    -- |
    --  Module      :  Ruleset
    --  Copyright   :  (c) 2003, Graham Klyne, 2009 Vasili I Galchin, 2011, 2012 Douglas Burke
    --  License     :  GPL V2
    --
    --  Maintainer  :  Douglas Burke
    --  Stability   :  experimental
    --  Portability :  H98
    --
    --  This module defines a ruleset data type, used to collect information
    --  about a ruleset that may contribute torwards inferences in RDF;
    --  e.g. RDF and RDFS are rulesets.
    --
    --  A 'Ruleset' consists of a namespace, a collection of axioms, and
    --  a collection of rules.
    --
    --------------------------------------------------------------------------------

    module Swish.Ruleset
        ( Ruleset(..), RulesetMap
        , makeRuleset, getRulesetNamespace, getRulesetAxioms, getRulesetRules
        , getRulesetAxiom, getRulesetRule
        , getContextAxiom, getMaybeContextAxiom
        , getContextRule,  getMaybeContextRule
        )
    where

    import Swish.Namespace (Namespace, ScopedName)
    import Swish.Rule (Formula(..), Rule(..))

    {-
    Used for the Show instance of Ruleset, which was
    used for debugging but has been removed as not
    really needed by the general user.

    import Swish.Utils.ShowM (ShowM(..))
    import Data.List (intercalate)
    -}

    import Data.Maybe (fromMaybe, listToMaybe, mapMaybe)

    import qualified Data.Map as M

    -- | A Rule set.

    data Ruleset ex = Ruleset
        { rsNamespace :: Namespace    -- ^ Namespace.
        , rsAxioms    :: [Formula ex] -- ^ Axioms.
        , rsRules     :: [Rule ex]    -- ^ Rules.
        }

    {-

    Used for debugging.

    instance (ShowM ex) => Show (Ruleset ex) where
      show (Ruleset ns axs rls) =
        intercalate "\n"
        [ "Ruleset: " ++ show ns
        , "Axioms:" ]
        ++ (showsFormulae "\n" axs
           (intercalate "\n" ("Rules:" : map show rls))) ""
    -}

    -- | Ruleset comparisons are based only on their namespace components.
    instance Eq (Ruleset ex) where
        r1 == r2 = rsNamespace r1 == rsNamespace r2

    -- | A set of Rulesets labelled by their Namespace.
    type RulesetMap ex = M.Map Namespace (Ruleset ex)

    -- | Create a ruleset.
    makeRuleset :: Namespace -> [Formula ex] -> [Rule ex] -> Ruleset ex
    makeRuleset nsp fms rls = Ruleset
        { rsNamespace = nsp
        , rsAxioms    = fms
        , rsRules     = rls
        }

    -- | Extract the namespace of a ruleset.
    getRulesetNamespace :: Ruleset ex -> Namespace
    getRulesetNamespace = rsNamespace

    -- | Extract the axioms from a ruleset.
    getRulesetAxioms :: Ruleset ex -> [Formula ex]
    getRulesetAxioms = rsAxioms

    -- | Extract the rules from a ruleset.
    getRulesetRules :: Ruleset ex -> [Rule ex]
    getRulesetRules = rsRules

    -- | Find a named axiom in a ruleset.
    getRulesetAxiom :: ScopedName -> Ruleset ex -> Maybe (Formula ex)
    getRulesetAxiom nam rset =
        M.lookup nam $ M.fromList $ map (\f -> (formName f, f)) (rsAxioms rset)

    -- | Find a named rule in a ruleset.
    getRulesetRule :: ScopedName -> Ruleset ex -> Maybe (Rule ex)
    getRulesetRule nam rset =
        M.lookup nam $ M.fromList $ map (\r -> (ruleName r, r)) (rsRules rset)

    -- | Find a named axiom in a proof context.
    getContextAxiom ::
      ScopedName -- ^ Name of axiom.
      -> Formula ex -- ^ Default axiom (used if named component does not exist).
      -> [Ruleset ex] -- ^ Rulesets to search.
      -> Formula ex
    getContextAxiom nam def rsets = fromMaybe def (getMaybeContextAxiom nam rsets)

    -- | Find a named axiom in a proof context.
    getMaybeContextAxiom ::
      ScopedName -- ^ Name of axiom.
      -> [Ruleset ex] -- ^ Rulesets to search.
      -> Maybe (Formula ex)
    getMaybeContextAxiom nam rsets =
        listToMaybe $ mapMaybe (getRulesetAxiom nam) rsets

    -- | Find a named rule in a proof context.
    getContextRule ::
      ScopedName -- ^ Name of rule.
      -> Rule ex -- ^ Default rule (used if named component does not exist).
      -> [Ruleset ex] -- ^ Rulesets to search.
      -> Rule ex
    getContextRule nam def rsets = fromMaybe def (getMaybeContextRule nam rsets)

    -- | Find a named rule in a proof context.
    getMaybeContextRule ::
      ScopedName -- ^ Name of rule.
      -> [Ruleset ex] -- ^ Rulesets to search.
      -> Maybe (Rule ex)
    getMaybeContextRule nam rsets =
        listToMaybe $ mapMaybe (getRulesetRule nam) rsets

    --------------------------------------------------------------------------------
    --
    --  Copyright (c) 2003, Graham Klyne, 2009 Vasili I Galchin,
    --    2011, 2012 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
    --
    --------------------------------------------------------------------------------