{-# LANGUAGE FlexibleInstances #-} ----------------------------------------------------------------------------- -- Copyright 2019, Advise-Me project team. This file is distributed under -- the terms of the Apache License 2.0. For more information, see the files -- "LICENSE.txt" and "NOTICE.txt", which are included in the distribution. ----------------------------------------------------------------------------- -- | -- Maintainer : bastiaan.heeren@ou.nl -- Stability : provisional -- Portability : portable (depends on ghc) -- -- This module defines the constraint data types. -- We differentiate between two constraint types: -- -- * Node constraint -- * regular constraint -- -- The regular constraint consists of a set of identifiers -- and a function that consumes some type @a@ and produces a `Result`. -- The set of identifiers come from combining constraints using the connectives -- defined in "Connectives". -- -- A Node constraint is simply a product of a Node Bool (the node) and a regular constraint. -- The constraint then corresponds to a node in one of the networks. -- ----------------------------------------------------------------------------- module Recognize.Model.Constraint where import Data.Monoid import qualified Data.Semigroup as SG import Recognize.Model.EvidenceBuilder import Recognize.Model.Result import Bayes.Network (Node) -- | Wraps over a constraint by giving it a specific node data NodeConstraint b m a = NodeConstraint { getNode :: Node b -- ^ The node of a constraint , getConstraint :: Constraint m a -- ^ The underlying constraint } -- | Models constraints that have an identifier and describe predicates that produce a result data Constraint m a = Constraint { getResult :: a -> m Result -- ^ Predicates that produces a `Result` given an @a@ } -- | Couple a constraint to a specific Node giveNode :: Node b -> Constraint m a -> NodeConstraint b m a giveNode = NodeConstraint -- | Makes a nodeconstraint: makeNodeConstraint :: Node b -> (a -> m Result) -> NodeConstraint b m a makeNodeConstraint node = NodeConstraint node . Constraint instance SG.Semigroup (Constraint EvBuilder a) where (Constraint mr1) <> (Constraint mr2) = Constraint (combinePredicates mr1 mr2) instance Monoid (Constraint EvBuilder a) where mempty = Constraint (\_ -> return Success) mappend = (SG.<>) -- | Combines two predicates into one combinePredicates :: (a -> EvBuilder Result) -> (a -> EvBuilder Result) -> a -> EvBuilder Result combinePredicates rm1 rm2 a = do r1 <- rm1 a r2 <- rm2 a return (r1 <> r2)