pointless-rewrite-0.0.3: src/Transform/Rules/Lenses/Products.hs
-----------------------------------------------------------------------------
-- |
-- Module : Transform.Rules.Lenses.Products
-- 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 lenses involving products.
--
-----------------------------------------------------------------------------
module Transform.Rules.Lenses.Products where
import Data.Type
import Data.Pf
import Data.Lens
import Data.Equal
import Transform.Rewriting
import Transform.Rules.Lenses.Combinators
import {-# SOURCE #-} qualified Transform.Rules.PF as PF
import Prelude hiding (Functor(..))
import Control.Monad hiding (Functor(..))
-- ** Product combinators
prod_functor_id_lns :: Rule
prod_functor_id_lns _ (PROD_LNS ID_LNS ID_LNS) =
success "prod-Functor-Id-Lns" ID_LNS
prod_functor_id_lns _ _ = mzero
prod_functor_comp_lns = comp_lns prod_functor_comp_lns'
prod_functor_comp_lns' :: Rule
prod_functor_comp_lns' (Lns _ _) (COMP_LNS (Prod c d) (f `PROD_LNS` g) (h `PROD_LNS` i)) =
success "prod-Functor-Comp-Lns" $ (COMP_LNS c f h) `PROD_LNS` (COMP_LNS d g i)
prod_functor_comp_lns' _ _ = mzero
fst_nat_lns = comp_lns fst_nat_lns'
fst_nat_lns' :: Rule
fst_nat_lns' q@(Lns (Prod c d) _ ) v@(COMP_LNS (Prod a b) (FST_LNS f) (l1 `PROD_LNS` l2)) = do
debug "fst-Nat-Lns" (Pf q) v
let g = COMP b (createof (Lns d b) l2) $ COMP a f (getof (Lns c a) l1)
g' <- PF.optimise_pf (Fun c d) g
success "fst-Nat-Lns" $ COMP_LNS c l1 $ FST_LNS g'
fst_nat_lns' _ _ = mzero
snd_nat_lns = comp_lns snd_nat_lns'
snd_nat_lns' :: Rule
snd_nat_lns' q@(Lns (Prod c d) _ ) v@(COMP_LNS (Prod a b) (SND_LNS f) (l1 `PROD_LNS` l2)) = do
debug "Snd-Nat-Lns" (Pf q) v
let g = COMP a (createof (Lns c a) l1) $ COMP b f (getof (Lns d b) l2)
g' <- PF.optimise_pf (Fun d c) g
success "snd-Nat-Lns" $ COMP_LNS d l2 $ SND_LNS g'
snd_nat_lns' _ _ = mzero
-- ** Isomorphisms involving products
bangl_cancel_lns = comp_lns bangl_cancel_lns'
bangl_cancel_lns' :: Rule
bangl_cancel_lns' (Lns _ _) (COMP_LNS _ (SND_LNS f) BANGL_LNS) =
success "bangl-Cancel-Lns" ID_LNS
bangl_cancel_lns' _ _ = mzero
bangr_cancel_lns = comp_lns bangr_cancel_lns'
bangr_cancel_lns' :: Rule
bangr_cancel_lns' (Lns _ _) (COMP_LNS _ (FST_LNS f) BANGR_LNS) =
success "bangr-Cancel-Lns" ID_LNS
bangr_cancel_lns' _ _ = mzero
swap_nat_lns = comp_lns swap_nat_lns'
swap_nat_lns' :: Rule
swap_nat_lns' (Lns (Prod a b) _) (COMP_LNS _ SWAP_LNS (PROD_LNS f g)) =
success "swap-Nat-Lns" $ COMP_LNS (Prod b a) (g `PROD_LNS` f) SWAP_LNS
swap_nat_lns' _ _ = mzero
swap_iso_lns = comp_lns swap_iso_lns'
swap_iso_lns' :: Rule
swap_iso_lns' (Lns _ _) (COMP_LNS _ SWAP_LNS SWAP_LNS) =
success "swap-Iso-Lns" ID_LNS
swap_iso_lns' _ _ = mzero
swap_cancel_lns = comp_lns swap_cancel_lns'
swap_cancel_lns' :: Rule
swap_cancel_lns' (Lns _ _) (COMP_LNS _ (FST_LNS f) SWAP_LNS) =
success "swap-Cancel-Lns" $ SND_LNS f
swap_cancel_lns' (Lns _ _) (COMP_LNS _ (SND_LNS f) SWAP_LNS) =
success "swap-Cancel-Lns" $ FST_LNS f
swap_cancel_lns' _ _ = mzero
assocr_nat_lns = comp_lns assocr_nat_lns'
assocr_nat_lns' :: Rule
assocr_nat_lns' (Lns _ (Prod a (Prod b c))) (COMP_LNS _ (f `PROD_LNS` (g `PROD_LNS` h)) ASSOCR_LNS) =
success "assocr-Nat-Lns" $ COMP_LNS (Prod (Prod a b) c) ASSOCR_LNS $ (f ><<< g) ><<< h
assocr_nat_lns' _ _ = mzero
assocr_iso_lns = comp_lns assocr_iso_lns'
assocr_iso_lns' :: Rule
assocr_iso_lns' (Lns _ _) (COMP_LNS _ ASSOCR_LNS ASSOCL_LNS) =
success "assocr-Iso-Lns" ID_LNS
assocr_iso_lns' _ _ = mzero
assocr_fst_cancel_lns = comp_lns assocr_fst_cancel_lns'
assocr_fst_cancel_lns' :: Rule
assocr_fst_cancel_lns' q@(Lns _ _) v@(COMP_LNS (Prod a (Prod b c)) (FST_LNS f) ASSOCR_LNS) = do
debug "assocr-Fst-Cancel-Lns" (Pf q) v
let h = COMP (Prod b c) SND $ COMP a f FST
g = COMP (Prod b c) FST f
h' <- PF.optimise_pf (Fun (Prod a b) c) h
g' <- PF.optimise_pf (Fun a b) g
success "assocr-Fst-Cancel-Lns" $ COMP_LNS (Prod a b) (FST_LNS g') (FST_LNS h')
assocr_fst_cancel_lns' (Lns _ _) (COMP_LNS (Prod a (Prod b c)) (ID_LNS `PROD_LNS` (FST_LNS f)) ASSOCR_LNS) = do
let g = COMP b f SND
success "assocr-Fst-Cancel-Lns" $ FST_LNS g
assocr_fst_cancel_lns' _ _ = mzero
assocr_snd_cancel_lns = comp_lns assocr_snd_cancel_lns'
assocr_snd_cancel_lns' :: Rule
assocr_snd_cancel_lns' (Lns _ _) (COMP_LNS _ (SND_LNS (COMP _ g FST)) ASSOCR_LNS) =
success "assocr-Snd-Cancel-Lns" $ (SND_LNS g) ><<< ID_LNS
assocr_snd_cancel_lns' (Lns _ _) (COMP_LNS (Prod a (Prod b c)) (ID_LNS `PROD_LNS` (SND_LNS (COMP _ f BANG))) ASSOCR_LNS) = do
let g = COMP One f BANG
success "assocr-Snd-Cancel-Lns" $ (FST_LNS g) ><<< ID_LNS
assocr_snd_cancel_lns' (Lns _ _) (COMP_LNS (Prod a (Prod b c)) (ID_LNS `PROD_LNS` (SND_LNS f)) ASSOCR_LNS) = do
Eq <- teq c a
success "assocr-Snd-Cancel-Lns" $ (FST_LNS f) ><<< ID_LNS
assocr_snd_cancel_lns' _ _ = mzero
assocl_nat_lns = comp_lns assocl_nat_lns'
assocl_nat_lns' :: Rule
assocl_nat_lns' (Lns _ (Prod (Prod a b) c)) (COMP_LNS _ ((f `PROD_LNS` g) `PROD_LNS` h) ASSOCL_LNS) =
success "assocl-Nat-Lns" $ COMP_LNS (Prod a (Prod b c)) ASSOCL_LNS $ f ><<< (g ><<< h)
assocl_nat_lns' _ _ = mzero
assocl_iso_lns = comp_lns assocl_iso_lns'
assocl_iso_lns' :: Rule
assocl_iso_lns' (Lns _ _) (COMP_LNS _ ASSOCL_LNS ASSOCR_LNS) =
success "assocl-Iso-Lns" ID_LNS
assocl_iso_lns' _ _ = mzero
assocl_fst_cancel_lns = comp_lns assocl_fst_cancel_lns'
assocl_fst_cancel_lns' :: Rule
assocl_fst_cancel_lns' (Lns _ _) (COMP_LNS _ (FST_LNS (COMP _ g SND)) ASSOCL_LNS) =
success "assocl-Fst-Cancel-Lns" $ ID_LNS ><<< FST_LNS g
assocl_fst_cancel_lns' (Lns _ _) (COMP_LNS _ ((FST_LNS (COMP _ f BANG)) `PROD_LNS` ID_LNS) ASSOCL_LNS) = do
let g = COMP One f BANG
success "assocl-Fst-Cancel-Lns" $ ID_LNS ><<< SND_LNS g
assocl_fst_cancel_lns' (Lns _ _) (COMP_LNS (Prod (Prod a b) c) ((FST_LNS f) `PROD_LNS` ID_LNS) ASSOCL_LNS) = do
Eq <- teq a c
success "assocl-Fst-Cancel-Lns" $ ID_LNS ><<< SND_LNS f
assocl_fst_cancel_lns' _ _ = mzero
assocl_snd_cancel_lns = comp_lns assocl_snd_cancel_lns'
assocl_snd_cancel_lns' :: Rule
assocl_snd_cancel_lns' q@(Lns _ _) v@(COMP_LNS (Prod (Prod a b) c) (SND_LNS f) ASSOCL_LNS) = do
debug "assocl-Snd-Cancel-Lns" (Pf q) v
let h = COMP (Prod a b) FST $ COMP c f SND
g = COMP (Prod a b) SND f
h' <- PF.optimise_pf (Fun (Prod b c) a) h
g' <- PF.optimise_pf (Fun c b) g
success "assocl-Snd-Cancel-Lns" $ COMP_LNS (Prod b c) (SND_LNS g') (SND_LNS h')
assocl_snd_cancel_lns' (Lns _ _) (COMP_LNS (Prod (Prod a b) c) ((SND_LNS f) `PROD_LNS` ID_LNS) ASSOCL_LNS) = do
let g = COMP b f FST
success "assocl-Snd-Cancel-Lns" $ SND_LNS g
assocl_snd_cancel_lns' _ _ = mzero
prods :: Rule
prods = top prod_functor_id_lns ||| top prod_functor_comp_lns
||| top fst_nat_lns ||| top snd_nat_lns ||| top bangl_cancel_lns ||| top bangr_cancel_lns
||| top swap_nat_lns ||| top swap_iso_lns ||| top swap_cancel_lns
||| top assocr_nat_lns ||| top assocr_iso_lns ||| top assocr_fst_cancel_lns ||| top assocr_snd_cancel_lns
||| top assocl_nat_lns ||| top assocl_iso_lns ||| top assocl_fst_cancel_lns ||| assocl_snd_cancel_lns