packages feed

transformations-0.2.0.0: examples/Regular.hs

{-# LANGUAGE FlexibleInstances  #-}
{-# LANGUAGE FlexibleContexts   #-}
{-# LANGUAGE TypeFamilies       #-}
{-# LANGUAGE TemplateHaskell    #-}
{-# LANGUAGE TypeOperators      #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE EmptyDataDecls     #-}
{-# LANGUAGE PatternSynonyms    #-}

module Regular where

import Datatypes
import Generics.Regular hiding (right)
import Generics.Regular.Transformations.Main
import Generics.Regular.Zipper

import Control.Monad ( (>=>) )
import Data.Maybe (fromJust)

--------------------------------------------------------------------------------
-- Regular representations for the example datatypes
--------------------------------------------------------------------------------
--Trees
$(deriveAll ''Tree "PFTree")
type instance PF Tree = PFTree

-- Lists
$(deriveAll ''List "PFL")
type instance PF (List a) = PFL a

-- Something more exotic
$(deriveAll ''X "PFX")
type instance PF X = PFX

-- Example for paper
$(deriveAll ''AExpr "PFExpr")
type instance PF Expr = PFExpr

deriving instance Ord AExpr

-- Datatype patterns
pattern Var'   x = In (InR (L (C (K x))))
pattern Const' x = In (InR (R (L (C (K x)))))
pattern Neg'   x = In (InR (R (R (L (C (I x))))))
pattern Add' x y = In (InR (R (R (R (C (I x :*: I y))))))

pattern Ref' x  = In (Ref x)

-- Path patterns
pattern End     = []
pattern Neg_0 x = CR (CR (CL (CC CId))) : x
pattern Add_0 x = CR (CR (CR (CC (C1 CId (I ()))))) : x
pattern Add_1 x = CR (CR (CR (CC (C2 (I ()) CId)))) : x

{-
type instance PF Expr = K String :+: K Integer :+: I :+: I :*: I

instance Regular Expr where
  from  (Var s)       = L (K s)
  from  (Const i)     = R (L (K i))
  from  (Neg e)       = R (R (L (I e)))
  from  (Add e1 e2)   = R (R (R (I e1 :*: I e2)))

  to (L (K s))                    = Var s
  to (R (L (K i)))                = Const i
  to (R (R (L (I e))))            = Neg e
  to (R (R (R (I e1 :*: I e2))))  = Add e1 e2
-}

--------------------------------------------------------------------------------
-- Examples for the paper
--------------------------------------------------------------------------------
instance Transform Expr

-- Some example values
expr1 :: Expr
expr1 = Add (Const 1) (Var "a")

expr2 :: Expr
expr2 = Add (Const 1) (Neg (Var "a"))

expr3 :: Expr
expr3 = Add (Var "a") (Const 1)

explicitIns :: Maybe Expr
explicitIns = apply addNeg expr1
  where addNeg :: Transformation Expr
        addNeg = diff expr1 expr2

-- Testing the nicer notation for paths and expressions with references
test1 :: Fix (WithRef Expr)
test1 = Neg' (Ref' test2)

test2 :: Path Expr
test2 = Add_1 End

test3 :: Transformation Expr
test3 = [(test2, test1)]

test4 :: Bool
test4 = show test3 == show (diff expr1 expr2)

-- Deletion (expr2 => expr1)
explicitDel :: Maybe Expr
explicitDel = apply delNeg expr2
  where delNeg :: Transformation Expr
        delNeg = diff expr2 expr1 --[ ([1], In (Ref [1,0])) ]

-- Swapping (expr1 => expr3)
explicitSwap :: Maybe Expr
explicitSwap = apply swap' expr1
  where swap' :: Transformation Expr
        swap' = diff expr1 expr3 -- [ ([0], In $ Ref [1]), ([1], In $ Ref [0])]

-- Rotation
rotate1 = Add (Var "a") (Add (Var "b") (Var "c"))
rotate2 = Add (Add (Var "a") (Var "b")) (Var "c")
rotate = diff rotate1 rotate2