packages feed

guarded-rewriting-0.1: examples/Test.hs

{-# LANGUAGE DeriveDataTypeable     #-}
{-# LANGUAGE TypeFamilies           #-}
{-# LANGUAGE TypeOperators          #-}
{-# LANGUAGE FlexibleInstances      #-}

module Test where

import Generics.Instant
import Generics.Instant.Rewriting

-------------------------------------------------------------------------------
-- Simple Datatype
-------------------------------------------------------------------------------

-- Example datatype
data Exp = Const Int | Plus Exp Exp deriving (Show, Typeable, Eq)

-- Representable instance
instance Representable Exp where
  type Rep Exp = Var Int :+: Rec Exp :*: Rec Exp

  from (Const n)   = L (Var n)
  from (Plus e e') = R (Rec e :*: Rec e')

  to (L (Var n))            = Const n
  to (R (Rec e :*: Rec e')) = Plus e e'

-- Required Rewritable instance
instance Rewritable Exp

-- An example rule
silly :: Rule Exp
silly = synthesise $ \e n ->
           Plus e (Const n)  +->  e    // n == 0

-- Applying the rewriting mechanism
test1 :: String
test1 = show $ rewrite silly (Plus (Const 2) (Const 0))

-------------------------------------------------------------------------------
-- Mutually recursive datatypes
-------------------------------------------------------------------------------

data Decl = None | Seq Decl Decl | Assign String Expr
  deriving (Show, Typeable, Eq)

data Expr = V String | Lam String Expr | App Expr Expr | Let Decl Expr
  deriving (Show, Typeable, Eq)

instance Representable Decl where
  type Rep Decl = U :+: Rec Decl :*: Rec Decl :+: Var String :*: Rec Expr

  from None         = L U
  from (Seq d1 d2)  = R (L (Rec d1 :*: Rec d2))
  from (Assign v e) = R (R (Var v :*: Rec e))

  to (L U)                       = None
  to (R (L (Rec d1 :*: Rec d2))) = Seq d1 d2
  to (R (R (Var v :*: Rec e)))   = Assign v e

instance Representable Expr where
  type Rep Expr =     Var String :+: Var String :*: Rec Expr
                 :+: Rec Expr :*: Rec Expr :+: Rec Decl :*: Rec Expr

  from (V x)     = L (Var x)
  from (Lam v e) = R (L (Var v :*: Rec e))
  from (App f e) = R (R (L (Rec f :*: Rec e)))
  from (Let d e) = R (R (R (Rec d :*: Rec e)))

  to (L (Var x))                   = V x
  to (R (L (Var v :*: Rec e)))     = Lam v e
  to (R (R (L (Rec f :*: Rec e)))) = App f e
  to (R (R (R (Rec d :*: Rec e)))) = Let d e
              
instance Rewritable Decl
instance Rewritable Expr
instance Rewritable [Char]

remLet :: Rule Expr
remLet = synthesise $ \x e -> Let (Assign x e) (V x) +-> e

remX :: Rule Decl
remX = synthesise $ \v e -> Assign v e +-> None // v == "x"

test2 :: String
test2 = show $ rewrite remLet (Let (Assign "x" (V "y")) (V "x"))

test3 :: String
test3 = show $ rewrite remX (Assign "x" (V "y"))


main = print [test1, test2, test3]