packages feed

pointless-rewrite-0.0.3: src/Transform/Rules/PF/Monoids.hs

-----------------------------------------------------------------------------
-- |
-- Module      :  Transform.Rules.PF.Monoids
-- Copyright   :  (c) 2010 University of Minho
-- License     :  BSD3
--
-- Maintainer  :  hpacheco@di.uminho.pt
-- Stability   :  experimental
-- Portability :  non-portable
--
-- Pointless Rewrite:
-- automatic transformation system for point-free programs
-- 
-- Combinators for the rewriting of point-free functions involving monoids.
--
-----------------------------------------------------------------------------

module Transform.Rules.PF.Monoids where

import Generics.Pointless.Functors hiding (rep)
import Transform.Rewriting
import {-# SOURCE #-} Transform.Rules.PF
import Transform.Rules.PF.Combinators
import Transform.Rules.PF.Products
import Transform.Rules.PF.Sums
import Data.Type
import Data.Pf
import Data.Equal

import Control.Monad hiding (Functor)
import Data.Monoid hiding (Any)
import Prelude hiding (Functor)

cata_zero :: Rule
cata_zero (Fun a r@(isList -> Just Eq)) (CATA f) = cata_zero' (Fun a r) (CATA f)
cata_zero (Fun a r@(isInt -> Just Eq)) (CATA f) = cata_zero' (Fun a r) (CATA f)
cata_zero (Fun a r@(isNat -> Just Eq)) (CATA f) = cata_zero' (Fun a r) (CATA f)
cata_zero _ _ = mzero

cata_zero' :: (Mu a,Functor (PF a),Monoid r) => Type (a -> r) -> Pf (a -> r) -> Rewrite (Pf (a -> r))
cata_zero' (Fun a@(dataFctr -> Just fctr) r) (CATA f) = do
    let (fa,fr) = (rep fctr a,rep fctr r)
        g' = COMP fr f (FMAP fctr (Fun a r) ZERO)
    g <- optimise_pf (Fun fa r) g'
    guard $ geq (Pf $ Fun fa r) ZERO g
    success "cata-Zero" ZERO

plus_zero, plus_zero' :: Rule
plus_zero = comp plus_zero'
plus_zero' _ (COMP _ PLUS (ZERO `SPLIT` f)) = success "plus-Zero" f
plus_zero' (Fun (Prod a b) _) (COMP _ PLUS (ZERO `PROD` f)) = success "plus-Zero" $ COMP b f SND
plus_zero' _ (COMP _ PLUS (f `SPLIT` ZERO)) = success "plus-Zero" f
plus_zero' (Fun (Prod a b) _) (COMP _ PLUS (f `PROD` ZERO)) = success "plus-Zero" $ COMP a f FST
plus_zero' _ _ = mzero

zero_fusion, zero_fusion' :: Rule
zero_fusion = comp zero_fusion'
zero_fusion' _ (COMP _ ZERO f) = success "zero-Fusion" ZERO
zero_fusion' _ _ = mzero

zero_either :: Rule
zero_either _ (ZERO `EITHER` ZERO) = success "zero-Either" ZERO
zero_either _ _ = mzero

fold_plus, fold_plus' :: Rule
fold_plus = comp fold_plus'
fold_plus' (Fun _ r) (COMP _ FOLD PLUS) = success "fold-Plus" $ COMP (Prod r r) PLUS (FOLD `PROD` FOLD)
fold_plus' _ _ = mzero

fold_zero, fold_zero' :: Rule
fold_zero = comp fold_zero'
fold_zero' _ (COMP _ FOLD ZERO) = success "fold-Zero" ZERO
fold_zero' _ _ = mzero

monoids :: Rule
monoids = top plus_zero ||| top zero_fusion ||| top fold_plus ||| top fold_zero ||| top zero_either