ideas-1.0: src/Common/Predicate.hs
{-# LANGUAGE ExistentialQuantification #-}
-----------------------------------------------------------------------------
-- Copyright 2011, Open Universiteit Nederland. This file is distributed
-- under the terms of the GNU General Public License. For more information,
-- see the file "LICENSE.txt", which is included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer : bastiaan.heeren@ou.nl
-- Stability : provisional
-- Portability : portable (depends on ghc)
--
-- Representation for predicates
--
-----------------------------------------------------------------------------
module Common.Predicate
( -- * Predicate representation
Predicate, predicate, predicateView
, evalPredicate
-- * Exports from Boolean algebra
, BoolValue(..), Boolean(..)
, ands, ors, implies, equivalent
) where
import Common.Algebra.Boolean
import Common.Id
import Common.View
data Predicate a
= Const Bool
| Prim (a -> Bool)
| forall b . PView (View a b)
| Compl (Predicate a)
| Predicate a :&&: Predicate a
| Predicate a :||: Predicate a
| Id :@ Predicate a
instance BoolValue (Predicate a) where
fromBool = Const
isTrue (Const b) = b
isTrue _ = False
isFalse (Const b) = not b
isFalse _ = False
instance Boolean (Predicate a) where
Const b <&&> y = if b then y else false
x <&&> Const b = if b then x else false
x <&&> y = x :&&: y
Const b <||> y = if b then true else y
x <||> Const b = if b then true else x
x <||> y = x :||: y
complement (Const b) = Const (not b)
complement x = Compl x
instance HasId (Predicate a) where
getId (n :@ _) = n
getId (PView v) = getId v
getId _ = mempty
changeId f (n :@ a) = f n :@ a
changeId f a = f mempty :@ a
instance Identify (Predicate a) where
n @> v | isEmptyId a = v
| otherwise = a :@ v
where
a = newId n
predicate :: (a -> Bool) -> Predicate a
predicate = Prim
predicateView :: View a b -> Predicate a
predicateView = PView
evalPredicate :: Predicate a -> a -> Bool
evalPredicate p a = rec p
where
rec (Const b) = b
rec (Prim f) = f a
rec (PView v) = a `belongsTo` v
rec (Compl x) = not (rec x)
rec (x :&&: y) = rec x && rec y
rec (x :||: y) = rec x || rec y
rec (_ :@ x) = rec x