ideas-0.7: src/Common/Rewriting/Operator.hs
-----------------------------------------------------------------------------
-- Copyright 2010, 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)
--
-----------------------------------------------------------------------------
module Common.Rewriting.Operator
( -- * Constants
Constant, makeConstant, simpleConstant
, constant, isConstant, constantView
-- * Unary operators
, UnaryOp, makeUnary, simpleUnary
, unary, isUnary, unaryMatch, unaryView
-- * Binary operators
, BinaryOp, makeBinary, simpleBinary
, binary, isBinary, binaryMatch, binaryView
) where
import Common.Id
import Common.Uniplate
import Common.View
import Data.Maybe
import Control.Monad
----------------------------------------------------------------------
-- Constants
data Constant a = C
{ constantId :: Id
, constant :: a
, isConstant :: a -> Bool
}
instance Show (Constant a) where
show = showId
instance HasId (Constant a) where
getId = constantId
changeId f op = op {constantId = f (constantId op)}
makeConstant :: IsId n => n -> a -> (a -> Bool) -> Constant a
makeConstant = C . newId
simpleConstant :: (IsId n, Eq a) => n -> a -> Constant a
simpleConstant n a = makeConstant n a (==a)
constantView :: Constant a -> View a ()
constantView (C i a p) = newView i (guard . p) (const a)
----------------------------------------------------------------------
-- Unary operators
data UnaryOp a = U
{ unaryId :: Id
, unary :: a -> a
, unaryMatch :: a -> Maybe a
}
instance Show (UnaryOp a) where
show = showId
instance HasId (UnaryOp a) where
getId = unaryId
changeId f op = op {unaryId = f (unaryId op)}
makeUnary :: IsId n => n -> (a -> a) -> (a -> Maybe a) -> UnaryOp a
makeUnary = U . newId
simpleUnary :: (IsId n, Uniplate a, Eq a) => n -> (a -> a) -> UnaryOp a
simpleUnary n op = makeUnary n op f
where
f a = case children a of
[x] | op x == a -> Just x
_ -> Nothing
isUnary :: UnaryOp a -> a -> Bool
isUnary op = isJust . unaryMatch op
unaryView :: UnaryOp a -> View a a
unaryView (U i op m) = newView i m op
----------------------------------------------------------------------
-- Binary operators
data BinaryOp a = B
{ binaryId :: Id
, binary :: a -> a -> a
, binaryMatch :: a -> Maybe (a, a)
}
instance Show (BinaryOp a) where
show = showId
instance HasId (BinaryOp a) where
getId = binaryId
changeId f op = op {binaryId = f (binaryId op)}
makeBinary :: IsId n => n -> (a -> a -> a) -> (a -> Maybe (a, a)) -> BinaryOp a
makeBinary = B . newId
simpleBinary :: (IsId n, Uniplate a, Eq a) => n -> (a -> a -> a) -> BinaryOp a
simpleBinary n op = makeBinary n op f
where
f a = case children a of
[x, y] | op x y == a -> Just (x, y)
_ -> Nothing
isBinary :: BinaryOp a -> a -> Bool
isBinary op = isJust . binaryMatch op
binaryView :: BinaryOp a -> View a (a, a)
binaryView (B n op m) = newView n m (uncurry op)