packages feed

transformations (empty) → 0.1.0.0

raw patch · 22 files changed

+3232/−0 lines, 22 filesdep +basedep +containersdep +mtlsetup-changed

Dependencies added: base, containers, mtl, multirec, parsec, regular, rewriting, zipper

Files

+ Generics/MultiRec/Any.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE GADTs                 #-}
+
+module Generics.MultiRec.Any where
+
+import Generics.MultiRec
+
+data Any phi where
+  Any :: phi ix -> ix -> Any phi
+
+-- | Unify an 'Any' with an @a@.
+matchAny :: forall phi ix. EqS phi => phi ix -> Any phi -> Maybe ix
+matchAny p (Any w x) = match' w x p where
+  match' :: EqS s => s b -> b -> s a -> Maybe a
+  match' w x w' = case eqS w w' of
+    Nothing -> Nothing
+    Just Refl -> Just x
+ Generics/MultiRec/HZip.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE GADTs                 #-}
+
+module Generics.MultiRec.HZip where
+
+import Generics.MultiRec
+import Control.Monad (liftM, liftM2, zipWithM)
+
+class HZip phi f where
+  hzipM :: Monad m =>
+           (forall ix. El phi ix => phi ix -> r ix -> r' ix -> m (r'' ix)) ->
+           f r ix -> f r' ix -> m (f r'' ix)
+
+instance El phi xi => HZip phi (I xi) where
+  hzipM f (I x) (I y) = liftM I (f proof x y)
+
+instance Eq a => HZip phi (K a) where
+  hzipM f (K x) (K y) | x == y    = return (K x)
+                      | otherwise = fail "zip failed in K"
+
+instance HZip phi U where
+  hzipM f U U = return U
+
+instance (HZip phi a, HZip phi b) => HZip phi (a :+: b) where
+  hzipM f (L x) (L y) = liftM L (hzipM f x y)
+  hzipM f (R x) (R y) = liftM R (hzipM f x y)
+  hzipM f _     _     = fail "zip failed"
+
+instance (HZip phi a, HZip phi b) => HZip phi (a :*: b) where
+  hzipM f (x1 :*: y1) (x2 :*: y2) = liftM2 (:*:) (hzipM f x1 x2) (hzipM f y1 y2)
+
+instance HZip phi f => HZip phi (f :>: xi) where
+  hzipM f (Tag x) (Tag y) = liftM Tag (hzipM f x y)
+
+instance HZip phi f => HZip phi (C c f) where
+  hzipM f (C x) (C y) = liftM C (hzipM f x y)
+
+instance HZip phi f => HZip phi ([] :.: f) where
+  hzipM f (D x) (D y) = liftM D (zipWithM (hzipM f) x y)
+
+-- | Monadic zip but argument is not monadic
+hzip :: (HZip phi f, Monad m) =>
+        (forall ix. El phi ix => phi ix -> r ix -> s ix -> t ix) ->
+        phi ix -> f r ix -> f s ix -> m (f t ix)
+hzip f p = hzipM (\w x y -> return (f w x y))
+
+-- | Unsafe zip
+hzip' :: (HZip phi f) =>
+         (forall ix. El phi ix => phi ix -> r ix -> s ix -> t ix) ->
+         phi ix -> f r ix -> f s ix -> f t ix
+hzip' f p a b = case hzip (\p x y -> f p x y) p a b of
+  Nothing  -> error "generic zip failed"
+  Just res -> res
+
+-- | Combine two structures monadically only
+combine :: forall phi f r r' m ix. (Monad m, HZip phi f) =>
+           (forall ix. El phi ix => phi ix -> r ix -> r' ix -> m ()) ->
+           phi ix -> f r ix -> f r' ix -> m ()
+combine f l x y = hzipM wrapf x y >> return ()
+  where
+    wrapf :: forall ix' b. El phi ix' => phi ix' -> r ix' -> r' ix' -> m (K0 () b)
+    wrapf ix x y = f ix x y >> return (K0 ())
+
+-- | Generic equality
+geq :: (Fam phi, HZip phi (PF phi)) => phi ix -> ix -> ix -> Bool
+geq ix x y = maybe False (const True) (geq' ix (I0 x) (I0 y))
+
+-- | Monadic generic equality (just for the sake of the monad!)
+geq' :: (Monad m, Fam phi, HZip phi (PF phi))
+        => phi ix -> I0 ix -> I0 ix -> m ()
+geq' p (I0 x) (I0 y) = combine geq' p (from p x) (from p y)
+ Generics/MultiRec/LR.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE GADTs                 #-}
+
+module Generics.MultiRec.LR where
+
+import Generics.MultiRec
+
+-----------------------------------------------------------------------------
+-- Functions for generating values that are different on top-level.
+-----------------------------------------------------------------------------
+
+-- | The @LRBase@ class defines two functions, @leftb@ and @rightb@, which 
+-- should produce different values.
+class LRBase a where
+  leftb  :: a
+  rightb :: a
+
+instance LRBase Int where
+  leftb  = 0
+  rightb = 1
+
+instance LRBase Integer where
+  leftb  = 0
+  rightb = 1
+
+instance LRBase Char where
+  leftb  = 'L'
+  rightb = 'R'
+ 
+instance LRBase Bool where
+  leftb  = True
+  rightb = False
+
+instance LRBase a => LRBase [a] where
+  leftb  = []
+  rightb = [rightb]
+
+-- | The @LR@ class defines two functions, @leftf@ and @rightf@, which should 
+-- produce different functorial values.
+class LR phi (f :: (* -> *) -> * -> *) where
+--    leftf  :: s ix -> (forall ix . Ix s ix => s ix -> r ix) -> [f s r ix]
+  leftf  :: phi ix -> (forall ix'. El phi ix' => phi ix' -> r ix') -> [f r ix]
+  rightf :: phi ix -> (forall ix'. El phi ix' => phi ix' -> r ix') -> [f r ix]
+ 
+instance El phi xi => LR phi (I xi) where
+  leftf  _ f = [I (f proof)]
+  rightf _ f = [I (f proof)]
+
+instance LRBase a => LR phi (K a) where
+  leftf  _ _ = [K leftb]
+  rightf _ _ = [K rightb]
+
+instance LR phi U where
+  leftf  _ _ = [U]
+  rightf _ _ = [U]
+
+instance (LR phi f, LR phi g) => LR phi (f :+: g) where
+  leftf  p f = map L (leftf  p f) ++ map R (leftf  p f)
+  rightf p f = map R (rightf p f) ++ map L (rightf p f)
+
+instance (LR phi f, LR phi g) => LR phi (f :*: g) where
+  leftf  p f = zipWith (:*:) (leftf  p f) (leftf  p f)
+  rightf p f = zipWith (:*:) (rightf p f) (rightf p f)
+
+instance LR phi f => LR phi (C c f) where
+  leftf  p f = map C (leftf  p f)
+  rightf p f = map C (rightf p f)
+
+instance (El phi ix, LR phi f, EqS phi) => LR phi (f :>: ix) where
+  leftf  p f = case eqS (proof :: phi ix) p of
+    Just Refl -> map Tag (leftf  p f)
+    Nothing   -> []
+  rightf p f = case eqS (proof :: phi ix) p of
+    Just Refl -> map Tag (rightf  p f)
+    Nothing   -> []
+
+instance LR phi f => LR phi ([] :.: f) where
+  leftf  p f = [D []]
+  rightf p f = map (\v -> D [v]) $ rightf p f
+
+left :: (Fam phi, LR phi (PF phi)) => phi ix -> ix
+left p = to p $ safeHead $ leftf p (I0 . left)
+
+right :: (Fam phi, LR phi (PF phi)) => phi ix -> ix
+right p = to p $ safeHead $ rightf p (I0 . right)
+
+safeHead [] = error "Internal error, left or right returned []"
+safeHead (x:xs) = x
+ Generics/MultiRec/Ord.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE GADTs                 #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+
+module Generics.MultiRec.Ord where
+
+import Generics.MultiRec
+import Data.Monoid (mappend)
+
+--------------------------------------------------------------------------------
+-- Generic Ord
+--------------------------------------------------------------------------------
+class HOrd phi f where
+  hcompare :: (forall ix. phi ix -> r ix -> r ix -> Ordering) 
+              -> phi ix -> f r ix -> f r ix -> Ordering
+
+instance El phi xi => HOrd phi (I xi) where
+  hcompare f _ (I x) (I y) = f proof x y
+
+instance Ord a => HOrd phi (K a) where
+  hcompare _ _ (K x) (K y) = compare x y
+
+instance HOrd phi U where
+  hcompare _ _ U U = EQ
+
+instance (HOrd phi f, HOrd phi g) => HOrd phi (f :+: g) where
+  hcompare f p (L _) (R _) = LT
+  hcompare f p (R _) (L _) = GT
+  hcompare f p (L x) (L y) = hcompare f p x y
+  hcompare f p (R x) (R y) = hcompare f p x y
+
+instance (HOrd phi f, HOrd phi g) => HOrd phi (f :*: g) where
+  hcompare f p (v :*: x) (w :*: y) = hcompare f p v w `mappend` hcompare f p x y
+
+instance HOrd phi f => HOrd phi (C c f) where
+  hcompare f p (C x) (C y) = hcompare f p x y
+
+instance HOrd phi f => HOrd phi (f :>: ix) where
+  hcompare f p (Tag x) (Tag y) = hcompare f p x y
+
+instance (Ord1 f, HOrd phi g) => HOrd phi (f :.: g) where
+  hcompare f p (D x) (D y) = compare1 (hcompare f p) x y
+
+class Ord1 f where
+  compare1 :: (a -> a -> Ordering) -> f a -> f a -> Ordering
+
+instance Ord1 [] where
+  compare1 f [] [] = EQ
+  compare1 f [] _  = LT
+  compare1 f _  [] = GT
+  compare1 f (x:xs) (y:ys) = f x y `mappend` compare1 f xs ys
+
+gcompare :: (Fam phi, HOrd phi (PF phi)) => phi ix -> ix -> ix -> Ordering
+gcompare p x1 x2 = hcompare (\ p (I0 x1) (I0 x2) -> gcompare p x1 x2) p (from p x1) (from p x2)
+ Generics/MultiRec/Rewriting.hs view
@@ -0,0 +1,7 @@+module Generics.MultiRec.Rewriting (
+  module Generics.MultiRec.Rewriting.Machinery,
+  module Generics.MultiRec.Rewriting.Rules,
+) where
+
+import Generics.MultiRec.Rewriting.Machinery
+import Generics.MultiRec.Rewriting.Rules
+ Generics/MultiRec/Rewriting/Machinery.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE GADTs                 #-}
+
+module Generics.MultiRec.Rewriting.Machinery where
+
+import Generics.MultiRec
+import Generics.MultiRec.HZip
+import Generics.MultiRec.Rewriting.Rules
+import Generics.MultiRec.Any
+
+import qualified Data.Map as M
+import Control.Monad.State
+
+-----------------------------------------------------------------------------
+-- Class synonym for shorter names
+-----------------------------------------------------------------------------
+class (Fam phi, EqS phi, HZip phi (PF phi), HFunctor phi (PF phi))
+      => Rewrite phi
+
+-----------------------------------------------------------------------------
+-- Actual rewriting
+-----------------------------------------------------------------------------
+rewriteM :: Rewrite phi => Rule phi a -> a -> Maybe a
+rewriteM (Rule p (lhs :~> rhs)) term = 
+  match p lhs term >>= return . (\s -> inst s p rhs)
+
+match :: (Monad m, Rewrite phi) => 
+         phi ix -> Scheme phi ix -> ix -> m (Subst phi)
+match p pat term = execStateT (matchM p pat (I0 term)) M.empty
+
+matchM :: (Monad m, Rewrite phi) 
+          => phi ix -> Scheme phi ix -> I0 ix -> StateT (Subst phi) m ()
+matchM p scheme (I0 e) = case scheme of
+  HIn (L (K var)) -> do 
+    subst <- get
+    case M.lookup var subst of
+      Nothing     -> put (M.insert var (Any p e) subst)
+      Just exTerm -> checkEqual p e exTerm
+  HIn (R r) -> combine matchM p r (from p e)
+
+checkEqual :: (Monad m, Rewrite phi)
+           => phi ix -> ix -> Any phi -> m ()
+checkEqual p e (Any p' e') = case eqS p p' of
+  Nothing   -> fail "checkEqual"
+  Just Refl -> geq' p (I0 e) (I0 e')
+
+inst :: Rewrite phi =>
+        Subst phi -> phi ix -> Scheme phi ix -> ix
+inst s ix p
+  = case p of
+     HIn (L (K x)) ->
+        case M.lookup x s of
+          Just (Any ix' e)
+            -> case eqS ix ix' of
+                 Just Refl -> e
+                 Nothing -> error "Coerce error in inst"
+     HIn (R r) -> to ix $ hmap (\ix' -> I0 . inst s ix') ix r
+
+type Subst phi = M.Map Metavar (Any phi)
+ Generics/MultiRec/Rewriting/Rules.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE GADTs                 #-}
+
+module Generics.MultiRec.Rewriting.Rules where
+
+import Generics.MultiRec
+import Generics.MultiRec.LR
+import Generics.MultiRec.HZip
+
+-----------------------------------------------------------------------------
+-- Rule specification.
+-----------------------------------------------------------------------------
+
+-- | Specifies a rule as a value of a datatype.
+infix 5 :~>
+data RuleSpec a = a :~> a
+
+-- | Returns the left-hand side of a rule.
+lhsR :: RuleSpec a -> a
+lhsR (x :~> _) = x
+
+-- | Returns the right-hand side of a rule.
+rhsR :: RuleSpec a -> a
+rhsR (_ :~> y) = y
+
+-----------------------------------------------------------------------------
+-- Representation of a rule.
+-----------------------------------------------------------------------------
+-- | Extends a pattern functor with a case for a metavariable.
+type Ext phi  = K Metavar :+: PF phi
+type Metavar  = Int
+
+-- | Recursively extends a type with a case for a metavariable.
+type Scheme phi = HFix (Ext phi)
+
+-- | Allows metavariables on either side of a rule.
+data Rule phi a where 
+  Rule :: phi ix -> RuleSpec (Scheme phi ix) -> Rule phi ix
+
+-- | Constructs a metavariable.
+metavar :: phi ix -> Metavar -> Scheme phi ix
+metavar _ = HIn . L . K
+
+pf :: phi ix -> PF phi (Scheme phi) ix -> Scheme phi ix
+pf _ = HIn . R
+
+-----------------------------------------------------------------------------
+-- Builder for transforming a rule specification to a rule.
+-----------------------------------------------------------------------------
+
+class Builder phi a where
+  type Target a :: *
+  base          :: phi (Target a) -> a -> RuleSpec (Target a)
+  diag          :: phi (Target a) -> a -> [RuleSpec (Target a)]
+
+instance Builder phi (RuleSpec a) where
+  type Target (RuleSpec a) = a
+  base _ x                 = x
+  diag _ x                 = [x]
+
+instance (Builder phi a, Fam phi, LR phi (PF phi), El phi b)
+         => Builder phi (b -> a) where
+  type Target (b -> a) = Target a
+  base ix f            = base ix (f (left  (proof :: phi b)))
+  diag ix f            = base ix (f (right (proof :: phi b))) :
+                         diag ix (f (left  (proof :: phi b)))
+
+rule :: forall phi r. (Fam phi, Builder phi r, HZip phi (PF phi), 
+                       El phi (Target r), EqS phi, HFunctor phi (PF phi))
+        => r -> Rule phi (Target r)
+rule f = Rule ix $ foldr1 mergeRules rules
+  where
+    ix = proof :: phi (Target r)
+    mergeRules x y = 
+      mergeSchemes ix (lhsR x) (lhsR y) :~>
+      mergeSchemes ix (rhsR x) (rhsR y)
+    rules          = zipWith (ins (base ix f)) (diag ix f) [0..]   
+    ins x y v      = 
+      insertMVar v ix (I0 (lhsR x)) (I0 (lhsR y)) :~>
+      insertMVar v ix (I0 (rhsR x)) (I0 (rhsR y))
+
+mergeSchemes :: HZip phi (PF phi)
+                => phi ix -> Scheme phi ix -> Scheme phi ix -> Scheme phi ix
+mergeSchemes p a@(HIn x) b@(HIn y) = case (x,y) of
+  (L _,_) -> a
+  (_,L _) -> b
+  _       -> HIn (hzip' mergeSchemes p x y)
+
+insertMVar :: forall phi ix. (Fam phi, HZip phi (PF phi), El phi ix)
+              => Metavar -> phi ix -> I0 ix -> I0 ix -> Scheme phi ix
+insertMVar name p (I0 x) (I0 y) =
+  case hzip (insertMVar name) p (from p x) (from p y) of
+    Just struc -> pf p struc
+    Nothing    -> metavar p name
+ Generics/MultiRec/Transformations/Explicit.hs view
@@ -0,0 +1,413 @@+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE GADTs                 #-}
+{-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+
+module Generics.MultiRec.Transformations.Explicit (
+  diff, apply, Transformation, AnyInsert (..), WithRef (..), Path, 
+  Transform, OrdI (..)
+  ) where
+
+import Generics.MultiRec.Any
+import Generics.MultiRec.Eq
+import Generics.MultiRec.Ord
+
+import Generics.MultiRec hiding (show, foldM)
+import Control.Applicative ( (<|>) )
+import Control.Monad (foldM)
+import Control.Monad.State hiding (foldM)
+import Data.Monoid (mappend)
+import qualified Data.Map as Map
+import Data.Map (Map)
+
+--------------------------------------------------------------------------------
+-- Paths, annotations, edits and existentials
+--------------------------------------------------------------------------------
+data WithRef phi f a = InR (PF phi f a)
+                     | Ref Path
+
+type Path = [Int]
+
+data AnyInsert phi where
+  AnyInsert :: phi ix -> Path -> HFix (WithRef phi) ix -> AnyInsert phi
+
+type Transformation phi = [ AnyInsert phi]
+
+class (Fam phi, Children phi (PF phi), CountI phi (PF phi),
+       HFunctor phi (PF phi), SEq phi (PF phi), ExtractN phi (PF phi), 
+       MapN phi (PF phi), EqS phi, HEq phi (PF phi), HOrd phi (PF phi),
+       OrdI phi) => Transform phi
+
+--------------------------------------------------------------------------------
+-- Applying
+--------------------------------------------------------------------------------
+-- | Apply the transformation to the given tree
+apply :: forall phi ix. (Transform phi)
+         => phi ix -> ix -> Transformation phi -> Maybe ix
+apply p t = foldM (apply' p) t where
+  apply' :: forall ix. phi ix -> ix -> AnyInsert phi -> Maybe ix
+  apply' p' _ (AnyInsert p'' [] c) = case eqS p' p'' of 
+    Just Refl -> lookupRefs p t p' c
+    Nothing   -> Nothing
+  apply' p' a (AnyInsert p'' (i:is) c) =
+    liftM (to p') $ tmapN f p' $ from p' a where
+      f :: forall ix. Int -> phi ix -> I0 ix -> Maybe (I0 ix)
+      f j p''' x | i == j    = liftM I0 (apply' p''' (unI0 x) (AnyInsert p'' is c))
+                 | otherwise = return x
+
+-- | Look up the references using the original structure
+lookupRefs :: forall phi ix ix'. (Fam phi, HFunctor phi (PF phi), ExtractN phi (PF phi), EqS phi) 
+              => phi ix -> ix -> phi ix' -> HFix (WithRef phi) ix' -> Maybe ix'
+lookupRefs p r p' = build .  hout where
+  build :: WithRef phi (HFix (WithRef phi)) ix' -> Maybe ix'
+  build (InR x) = liftM (to p') (hmapM (\p'' -> liftM I0 . lookupRefs p r p'') p' x)
+  build (Ref l) = extract l p r >>= matchAny p'
+
+-- | Extract the subtree at the given path
+extract :: (Fam phi, ExtractN phi (PF phi)) => Path -> phi ix -> ix -> Maybe (Any phi)
+extract []     p a = return $ Any p a
+extract (i:is) p a = extractN i p a >>= \(Any p' x) -> extract is p' x
+
+--------------------------------------------------------------------------------
+-- Memoisation
+--------------------------------------------------------------------------------
+-- | Comparing index of different types
+class OrdI phi where
+  compareI :: phi ix -> phi ix' -> Ordering
+
+-- | Key used in memoisation table
+data MemoKey phi where
+  MemoKey :: phi ix -> Bool -> ix -> ix -> MemoKey phi
+
+instance (EqS phi, Fam phi, HEq phi (PF phi)) => Eq (MemoKey phi) where
+  (MemoKey p1 a1 b1 c1) == (MemoKey p2 a2 b2 c2) = case eqS p1 p2 of
+    Nothing   -> False
+    Just Refl -> a1 == a2 && eq p1 b1 b2 && eq p1 c1 c2
+
+instance (EqS phi, Fam phi, OrdI phi, HEq phi (PF phi), HOrd phi (PF phi))
+         => Ord (MemoKey phi) where
+  compare (MemoKey p1 a1 b1 c1) (MemoKey p2 a2 b2 c2) = case eqS p1 p2 of
+    Nothing   -> compareI p1 p2
+    Just Refl -> compare a1 a2 `mappend` gcompare p1 b1 b2 
+                               `mappend` gcompare p1 c1 c2
+
+-- | The type of the memo table
+type MemoTable phi = Map (MemoKey phi) (Transformation phi)
+type Memo phi a = State (MemoTable phi) a
+
+runMemo :: Memo phi a -> a
+runMemo = flip evalState Map.empty
+
+recMemo :: (Fam phi, HEq phi (PF phi), HOrd phi (PF phi), EqS phi, OrdI phi) => 
+           (forall ix. Bool -> phi ix -> ix -> ix -> Memo phi (Transformation phi))
+           -> Bool -> phi ix -> ix -> ix -> Memo phi (Transformation phi)
+recMemo f a p b c = do
+  mp <- get
+  let k = MemoKey p a b c
+  case Map.lookup k mp of
+    Just r -> return r
+    Nothing -> do
+      r <- f a p b c
+      modify (Map.insert k r)
+      return r
+
+--------------------------------------------------------------------------------
+-- Diffing
+--------------------------------------------------------------------------------
+-- | Find a set of insertions to transform the first into the second tree
+diff :: forall phi ix. (Transform phi)
+        => phi ix -> ix -> ix -> Transformation phi
+diff p a b = runMemo (build False p a b)
+  where
+    childPaths :: [(Any phi, Path)]
+    childPaths = childrenPaths p a
+    build :: forall ix. Bool -> phi ix -> ix -> ix -> Memo phi (Transformation phi)
+    build False p' a' b' | eq p' a' b' = return []
+    build ins   p' a' b' = case anyLookup p' b' childPaths of
+      Just l  -> return [ AnyInsert p' [] (HIn $ Ref l) ]
+      Nothing -> uses >>= maybe insert return -- Only insert when we cannot reuse
+        where
+          -- Construct the edits for the children based on a root
+          construct :: Bool -> ix -> Memo phi (Maybe (Transformation phi))
+          construct ins' c = 
+            if shallowEq p' (from p' c) (from p' b')
+            then do r <- zipWithM (\(Any p1 c1) (Any p2 c2) -> case eqS p1 p2 of
+                                      Just Refl -> recMemo build ins' p1 c1 c2)
+                         (imChildren p' c) (imChildren p' b')
+                    return $ Just $ concat $ updateChildPaths r
+            else return Nothing
+          -- Possible edits reusing the existing tree or using a part of
+          -- the original tree. The existing tree is only used if we didn't
+          -- just insert it, since we want to keep the inserts small
+          uses :: Memo phi (Maybe (Transformation phi))
+          uses = reuses >>= \re -> case re of
+              Just r | ins -> return re
+              _            -> construct ins a' >>= return . pickBest re
+          -- Possible edits that include reusing a part of the original tree
+          reuses :: Memo phi (Maybe (Transformation phi))
+          reuses = foldM f Nothing childPaths where
+            addRef :: Path -> Maybe (Transformation phi) 
+                       -> Maybe (Transformation phi)
+            addRef l = liftM ((AnyInsert p' [] (HIn $ Ref l)):)
+            f c (Any p'' x, l) = case eqS p' p'' of
+              Just Refl -> construct False x >>= return . pickBest c . addRef l
+              Nothing   -> return c
+          -- Best edit including insertion, only chosen if nothing can be reused
+          insert :: Memo phi (Transformation phi)
+          insert = do
+            Just r <- construct True b'
+            let (r',e')  = partialApply p' (annotate p' b') r
+            return $ (AnyInsert p' [] r') : e'
+
+-- | Pick the best edit
+pickBest :: Maybe (Transformation phi) -> Maybe (Transformation phi) -> Maybe (Transformation phi)
+pickBest e1 e2 = case (e1,e2) of
+  (Just e1', Just e2') -> Just (pickShortest e1' e2')
+  _                    -> e1 <|> e2
+
+-- | Pick the shortest of two lists lazily
+pickShortest :: [a] -> [a] -> [a]
+pickShortest a b = if f a b then a else b
+  where f []     _      = True
+        f _      []     = False
+        f (_:xs) (_:ys) = f xs ys
+
+-- | Lookup with a specific type
+anyLookup :: (Fam phi, EqS phi, HEq phi (PF phi))
+             => phi ix -> ix -> [(Any phi, a)] -> Maybe a
+anyLookup p _ [] = Nothing
+anyLookup p x ((Any p' y,r) : ys) = case eqS p p' of
+  Just Refl | eq p x y -> Just r
+  _                    -> anyLookup p x ys
+
+-- | Lift a tree to an edit structure
+annotate :: (Fam phi, HFunctor phi (PF phi)) => phi ix -> ix -> HFix (WithRef phi) ix
+annotate p = HIn . InR . hmap (\p' (I0 x) -> annotate p' x) p . from p
+
+-- | Extend the paths of edits for the children with the child number
+updateChildPaths :: [Transformation phi] -> [Transformation phi]
+updateChildPaths = zipWith (\n -> map (\(AnyInsert p l c) -> (AnyInsert p (n:l) c))) [0..]
+
+-- | Try to apply as much edits to the edit structure as possible
+--   to make the final edit smaller
+partialApply :: (Fam phi, CountI phi (PF phi), ExtractN phi (PF phi), MapN phi (PF phi), EqS phi)
+                => phi ix -> HFix (WithRef phi) ix -> Transformation phi -> (HFix (WithRef phi) ix, Transformation phi)
+partialApply _ a [] = (a, [])
+partialApply p a (AnyInsert p' l x : xs) = case replace p' l x p a of
+  Just a' -> partialApply p a' xs
+  Nothing -> let (a',xs') = partialApply p a xs in (a', AnyInsert p' l x : xs')
+
+-- | Replace a subtree in an edit structure
+replace :: forall phi ix ix'. (Fam phi, EqS phi, MapN phi (PF phi))
+           => phi ix -> Path -> HFix (WithRef phi) ix
+           -> phi ix' -> HFix (WithRef phi) ix' -> Maybe (HFix (WithRef phi) ix')
+replace p [] r p' _ = case eqS p p' of
+  Just Refl -> Just r
+  Nothing   -> Nothing
+replace p (i:is) r p' a = case hout a of
+  Ref _  -> Nothing
+  InR a' -> liftM HIn . liftM InR . tmapN f p' $ a'
+    where f :: forall ix. Int -> phi ix -> HFix (WithRef phi) ix -> Maybe (HFix (WithRef phi) ix)
+          f j p'' = if i == j then replace p is r p'' else Just
+
+--------------------------------------------------------------------------------
+-- Shallow equality
+--------------------------------------------------------------------------------
+
+class SEq phi (f :: (* -> *) -> * -> *) where
+  shallowEq :: phi ix -> f r ix  -> f r ix -> Bool
+
+instance El phi xi => SEq phi (I xi) where
+  shallowEq _ (I _) (I _) = True
+
+instance SEq phi U where
+  shallowEq _ U U = True
+
+instance Eq a => SEq phi (K a) where
+  shallowEq p (K a) (K b) = a == b
+
+instance (SEq phi f, SEq phi g) => SEq phi (f :+: g) where
+  shallowEq p (L a) (L b) = shallowEq p a b
+  shallowEq p (R a) (R b) = shallowEq p a b
+  shallowEq _ _     _     = False
+
+instance (SEq phi f, SEq phi g) => SEq phi (f :*: g) where
+  shallowEq p (a :*: b) (c :*: d) = shallowEq p a c && shallowEq p b d
+
+instance SEq phi f => SEq phi (f :>: ix) where
+  shallowEq p (Tag a) (Tag b) = shallowEq p a b
+
+instance SEq phi f => SEq phi (C c f) where
+  shallowEq p (C a) (C b) = shallowEq p a b
+
+-- Todo: is this the best choice?
+instance SEq phi ([] :.: ix) where
+  shallowEq p (D a) (D b) = length a == length b
+
+--------------------------------------------------------------------------------
+-- ExtractN
+--------------------------------------------------------------------------------
+
+extractN :: (Fam phi, ExtractN phi (PF phi), Monad m) 
+            => Int -> phi ix -> ix -> m (Any phi)
+extractN i p v = extractN' (\p (I0 v) -> Any p v) i p (from p v)
+
+class ExtractN phi (f :: (* -> *) -> * -> *) where
+  extractN' :: Monad m => (forall ix. phi ix -> r ix -> r')
+                          -> Int -> phi ix -> f r ix -> m r'
+
+instance El phi xi => ExtractN phi (I xi) where
+  extractN' mka 0 _ (I r) = return $ mka proof r
+  extractN' _   _ _ (I _) = fail "extractN"
+
+instance ExtractN phi (K a) where
+  extractN' mka _ _ (K _) = fail "extractN"
+
+instance ExtractN phi U where
+  extractN' mka _ _ U = fail "extractN"
+
+instance (ExtractN phi f, ExtractN phi g) => ExtractN phi (f :+: g) where
+  extractN' mka i p (L x) = extractN' mka i p x
+  extractN' mka i p (R x) = extractN' mka i p x
+
+instance (CountI phi f, ExtractN phi f, ExtractN phi g) => ExtractN phi (f :*: g) where
+  extractN' mka i p (x :*: y) = let n = countI p x
+                                in if i < n then extractN' mka i     p x
+                                            else extractN' mka (i-n) p y
+
+instance ExtractN phi f => ExtractN phi (f :>: ix) where
+  extractN' mka i p (Tag x) = extractN' mka i p x
+
+instance ExtractN phi f => ExtractN phi (C c f) where
+  extractN' mka i p (C x) = extractN' mka i p x
+
+-- Todo: is this the best choice?
+instance ExtractN phi f => ExtractN phi ([] :.: f) where
+  extractN' mka i p (D x) = extractN' mka 0 p (x !! i)
+
+--------------------------------------------------------------------------------
+-- MapN
+--------------------------------------------------------------------------------
+
+-- | Map a function with child index at a top-level structure
+tmapN :: (Fam phi, MapN phi f, Monad m)
+         => (forall ix. Int -> phi ix -> r ix -> m (r' ix))
+         -> phi ix -> f r ix -> m (f r' ix)
+tmapN = mapN 0
+
+class MapN phi (f :: (* -> *) -> * -> *) where
+  mapN :: Monad m => Int -> (forall ix. Int -> phi ix -> r ix -> m (r' ix))
+                           -> phi ix -> f r ix -> m (f r' ix)
+
+instance El phi xi => MapN phi (I xi) where
+  mapN i f p (I x) = liftM I (f i proof x)
+
+instance MapN phi (K a) where
+  mapN _ _ _ (K x)  = return $ K x
+
+instance MapN phi U where
+  mapN _ _ _ U = return U
+
+instance (MapN phi f, MapN phi g) => MapN phi (f :+: g) where
+  mapN i f p (L x) = liftM L (mapN i f p x)
+  mapN i f p (R x) = liftM R (mapN i f p x)
+
+-- Here we increment our parameter. Does not require right-nested products
+instance (CountI phi f, MapN phi f, MapN phi g) => MapN phi (f :*: g) where
+  mapN i f p (x :*: y) = liftM2 (:*:) (mapN i f p x) (mapN (i + countI p x) f p y)
+
+instance MapN phi f => MapN phi (f :>: ix) where
+  mapN i f p (Tag x) = liftM Tag (mapN i f p x)
+
+instance MapN phi f => MapN phi (C c f) where
+  mapN i f p (C x) = liftM C (mapN i f p x)
+
+-- Todo: is this the best choice?
+instance (CountI phi f, MapN phi f) => MapN phi ([] :.: f) where
+  mapN i f p (D [])     = return $ D []
+  mapN i f p (D (x:xs)) = do h <- mapN i f p x
+                             t <- mapN (i + countI p x) f p (D xs)
+                             return $ D (h : unD t)
+
+--------------------------------------------------------------------------------
+-- CountI
+--------------------------------------------------------------------------------
+
+class CountI phi (f :: (* -> *) -> * -> *) where
+  -- | Count the number of recursive occurrences
+  countI :: phi ix -> f r ix -> Int
+
+instance El phi xi => CountI phi (I xi) where
+  countI _ _ = 1
+
+instance CountI phi (K a) where
+  countI _ _ = 0
+
+instance CountI phi U where
+  countI _ _ = 0
+
+instance (CountI phi f, CountI phi g) => CountI phi (f :+: g) where
+  countI p (L x) = countI p x
+  countI p (R x) = countI p x
+
+instance (CountI phi f, CountI phi g) => CountI phi (f :*: g) where
+  countI p (x :*: y) = countI p x + countI p y
+
+instance CountI phi f => CountI phi (f :>: ix) where
+  countI p (Tag x) = countI p x
+
+instance CountI phi f => CountI phi (C c f) where
+  countI p (C x) = countI p x
+
+-- Todo: is this the best choice?
+instance CountI phi f => CountI phi ([] :.: f) where
+  countI p (D x) = sum (map (countI p) x)
+
+--------------------------------------------------------------------------------
+-- Children
+--------------------------------------------------------------------------------
+
+-- | Get the immediate children
+imChildren :: (Fam phi, Children phi (PF phi)) => phi ix -> ix -> [Any phi]
+imChildren p x = children (\p (I0 v) -> Any p v) p (from p x)
+
+-- | Get all children with their paths
+childrenPaths :: (Fam phi, Children phi (PF phi)) => phi ix -> ix -> [(Any phi, Path)]
+childrenPaths p a = (Any p a, []) : 
+                    [ (r, n : p)
+                    | (n, Any p' c) <- zip [0..] (imChildren p a)
+                    , (r, p) <- childrenPaths p' c ]
+
+class Children phi (f :: (* -> *) -> * -> *) where
+  children :: (forall ix. phi ix -> r ix -> Any phi) -> phi ix -> f r ix -> [Any phi]
+
+instance (Fam phi, El phi xi) => Children phi (I xi) where
+  children mka _ (I r) = [mka proof r]
+
+instance Children phi (K a) where
+  children _ _ (K _) = []
+
+instance Children phi U where
+  children _ _ U = []
+
+instance (Children phi f, Children phi g) => Children phi (f :+: g) where
+  children mka p (L x) = children mka p x
+  children mka p (R x) = children mka p x
+
+instance (Children phi f, Children phi g) => Children phi (f :*: g) where
+  children mka p (x :*: y) = children mka p x ++ children mka p y
+
+instance Children phi f => Children phi (C c f) where
+  children mka p (C x) = children mka p x
+
+instance Children phi f => Children phi (f :>: ix) where
+  children mka p (Tag x) = children mka p x
+
+-- Todo: is this the best choice?
+instance Children phi f => Children phi ([] :.: f) where
+  children mka p (D x) = concatMap (children mka p) x
+ Generics/MultiRec/Transformations/RewriteRules.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE TypeFamilies               #-}
+{-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE EmptyDataDecls             #-}
+{-# LANGUAGE RankNTypes                 #-}
+{-# LANGUAGE GADTs                      #-}
+
+module Generics.MultiRec.Transformations.RewriteRules (
+  Transformation, Transform, apply, insert, AnyInsert (..)
+  ) where
+
+import Generics.MultiRec hiding ( foldM )
+import Generics.MultiRec.Rewriting
+import Generics.MultiRec.Zipper (Zipper, Loc, leave, enter, update)
+
+import Data.Maybe ( fromJust )
+import Control.Monad ( (>=>), foldM )
+
+--------------------------------------------------------------------------------
+-- Patch
+--------------------------------------------------------------------------------
+-- Basically, a class synonym
+class (Zipper phi (PF phi), Rewrite phi) => Transform phi
+instance Transform phi => Rewrite phi
+
+-- An edit is a list of:
+type Transformation phi a = [ AnyInsert phi a ]
+
+-- Existential for insertion
+data AnyInsert phi a where 
+  AnyInsert ::
+    -- Proof
+    phi ix
+    -- A path to the location to edit
+    -> (Loc phi I0 a -> Maybe (Loc phi I0 a)) 
+    -- The rewrite rule to apply there
+    -> Rule phi ix
+    -> AnyInsert phi a
+
+insert :: El phi ix => (Loc phi I0 a -> Maybe (Loc phi I0 a)) -> Rule phi ix
+          -> AnyInsert phi a
+insert = AnyInsert proof
+
+-- Patching is terribly simple: at the given locations, apply all the rules,
+-- then exit the zipper.
+apply :: Transform phi => Transformation phi a -> phi a -> a -> Maybe a
+apply rs p x = fmap leave $ foldM appRule (enter p x) rs
+  where appRule a (AnyInsert p' l r) = l a >>=
+                            updateM (\p'' -> case eqS p' p'' of
+                                              Nothing   -> const Nothing
+                                              Just Refl -> rewriteM r)
+
+updateM :: (forall xi. phi xi -> xi -> Maybe xi)
+        -> Loc phi I0 ix -> Maybe (Loc phi I0 ix)
+-- updateM f (Loc p (I0 x) s) = f p x >>= \y -> Loc p (I0 y) s
+updateM f = Just . update (\p -> maybe (error "updateM") id . f p)
+ Generics/MultiRec/Transformations/ZipperState.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE RankNTypes                 #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE GADTs                      #-}
+
+module Generics.MultiRec.Transformations.ZipperState (
+  ZipperMonad, ZipperState, upMonad, downMonad, leftMonad, rightMonad, 
+  navigate, saveMonad, loadMonad, topMonad, updateMonad
+  ) where
+
+import Control.Monad
+import Control.Monad.State
+
+import Generics.MultiRec
+import Generics.MultiRec.Zipper
+import Generics.MultiRec.Any
+
+--------------------------------------------------------------------------------
+-- A zipper with state
+--------------------------------------------------------------------------------
+
+type ZipperState phi r a = ([Any phi], Loc phi r a)
+type ZipperMonad phi r a b = StateT (ZipperState phi r a) Maybe b
+
+enterMonad :: (El phi a, Fam phi, Zipper phi (PF phi))
+           => a -> ZipperMonad phi I0 a (Any phi)
+enterMonad x = put ([], enter proof x) >> return (Any proof x)
+
+moveMonad :: (EqS phi, El phi a)
+          => (Loc phi I0 a -> Maybe (Loc phi I0 a))
+          -> ZipperMonad phi I0 a (Any phi)
+moveMonad d = StateT (\(s,l) -> do l' <- d l
+                                   let a = on (\p (I0 x) -> Any p x) l'
+                                   return (a, (s,l')))
+
+upMonad, downMonad, leftMonad, rightMonad :: (EqS phi, El phi a)
+                                          => ZipperMonad phi I0 a (Any phi)
+upMonad    = moveMonad up
+downMonad  = moveMonad down
+leftMonad  = moveMonad left
+rightMonad = moveMonad right
+
+updateMonad :: (EqS phi, El phi a)
+            => (forall xi. phi xi -> xi -> Maybe xi) 
+               -> ZipperMonad phi I0 a (Any phi)
+updateMonad f = do (s,l) <- get
+                   let l' = update (\p -> maybe (error "updateMonad") id . f p) l
+                       a  = on (\p (I0 x) -> Any p x) l'
+                   put (s,l')
+                   return a
+saveMonad :: (EqS phi, El phi a) => ZipperMonad phi I0 a (Any phi)
+saveMonad = do (s,l) <- get
+               let a = on (\p (I0 x) -> Any p x) l
+               put (s++[a],l)
+               return a
+
+loadMonad :: (EqS phi, El phi a) => ZipperMonad phi I0 a (Any phi)
+loadMonad = do (s:ss,l) <- get
+               let l' = update (\p x -> maybe x id (matchAny p s)) l
+               put (ss,l')
+               return s
+
+topMonad :: (EqS phi, El phi a) => ZipperMonad phi I0 a (Any phi)
+topMonad = moveMonad goUp where
+  goUp l = maybe (Just l) goUp (up l)
+
+leaveMonad :: (EqS phi, El phi a) 
+              => Loc phi I0 a -> ZipperMonad phi I0 a b -> Maybe a
+leaveMonad s m = maybe Nothing (matchAny proof) $ evalStateT (m >> topMonad) ([],s)
+
+navigate :: (Fam phi, EqS phi, El phi a, Zipper phi (PF phi))
+            => phi a -> a -> ZipperMonad phi I0 a b -> Maybe a
+navigate p x = leaveMonad (enter p x)
+ Generics/Regular/Functions/GOrd.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE TypeOperators              #-}
+{-# LANGUAGE FlexibleContexts           #-}
+
+module Generics.Regular.Functions.GOrd where
+
+import Generics.Regular
+import Data.Monoid (mappend)
+
+--------------------------------------------------------------------------------
+-- Generic Ord
+--------------------------------------------------------------------------------
+
+class GOrd f where
+  comparef :: (a -> a -> Ordering) -> f a -> f a -> Ordering
+
+instance GOrd I where
+  comparef f (I x) (I y) = f x y
+
+instance Ord a => GOrd (K a) where
+  comparef _ (K x) (K y) = compare x y
+
+instance GOrd U where
+  comparef _ U U = EQ
+
+instance (GOrd f, GOrd g) => GOrd (f :+: g) where
+  comparef _ (L _) (R _) = LT
+  comparef _ (R _) (L _) = GT
+  comparef f (L x) (L y) = comparef f x y
+  comparef f (R x) (R y) = comparef f x y
+
+instance (GOrd f, GOrd g) => GOrd (f :*: g) where
+  comparef f (x1 :*: y1) (x2 :*: y2) = comparef f x1 x2 `mappend` comparef f y1 y2
+
+instance GOrd f => GOrd (C c f) where
+  comparef f (C x) (C y) = comparef f x y
+
+instance GOrd f => GOrd (S s f) where
+  comparef f (S x) (S y) = comparef f x y
+
+gcompare :: (Regular a, GOrd (PF a)) => a -> a -> Ordering
+gcompare x y = comparef gcompare (from x) (from y)
+ Generics/Regular/Transformations/Explicit.hs view
@@ -0,0 +1,329 @@+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE GADTs                      #-}
+{-# LANGUAGE TypeOperators              #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE UndecidableInstances       #-}
+
+module Generics.Regular.Transformations.Explicit (
+  diff, apply, Transformation, WithRef (..), Path, Transform
+  ) where
+
+import Generics.Regular
+import Generics.Regular.Functions.GOrd
+import Control.Applicative ( (<|>) )
+import Control.Monad (foldM, liftM, liftM2)
+import Control.Monad.State
+import Data.Monoid (mappend)
+import qualified Data.Map as Map
+import Data.Map (Map)
+import qualified Generics.Regular.Functions.Eq as GEq
+
+--------------------------------------------------------------------------------
+-- Paths, annotations and edits
+--------------------------------------------------------------------------------
+type Path             = [Int]
+data WithRef a b      = InR (PF a b)
+                      | Ref Path
+type Transformation a = [ (Path, Fix (WithRef a)) ]
+
+class (Regular a, Children (PF a), CountI (PF a), Functor (PF a),
+       SEq (PF a), ExtractN (PF a), MapN (PF a), GMap (PF a), GOrd (PF a),
+       GEq.Eq (PF a)) => Transform a
+
+--------------------------------------------------------------------------------
+-- Patching
+--------------------------------------------------------------------------------
+
+-- | Apply the edits to the given tree
+apply :: Transform a => Transformation a -> a -> Maybe a
+apply e t = foldM apply' t e where
+  apply' _ ([],   c) = lookupRefs t c
+  apply' a (i:is, c) = fmap to . tmapN f . from $ a where
+    f j x | i == j     = apply' x (is,c)
+          | otherwise  = Just x
+
+-- | Look up the references using the original structure
+lookupRefs :: Transform a => a -> Fix (WithRef a) -> Maybe a
+lookupRefs r (In (InR a)) = fmap to (fmapM (lookupRefs r) a)
+lookupRefs r (In (Ref p)) = extract p r
+
+-- | Extract the subtree at the given path
+extract :: Transform a => Path -> a -> Maybe a
+extract p a = foldM (\x i -> extractN i $ from x) a p
+
+--------------------------------------------------------------------------------
+-- Diffing
+--------------------------------------------------------------------------------
+data MemoKey a where
+  MemoKey :: Bool -> a -> a -> MemoKey a
+
+instance (Regular a, GEq.Eq (PF a)) => Eq (MemoKey a) where
+  (MemoKey a1 b1 c1) == (MemoKey a2 b2 c2) =
+    a1 == a2 && GEq.eq b1 b2 && GEq.eq c1 c2
+
+instance (Regular a, GEq.Eq (PF a), GOrd (PF a)) => Ord (MemoKey a) where
+  compare (MemoKey a1 b1 c1) (MemoKey a2 b2 c2) =
+    compare a1 a2 `mappend` gcompare b1 b2 `mappend` gcompare c1 c2
+
+type Memo a = Map (MemoKey a) (Transformation a)
+
+-- | Find a set of edits to transform the first into the second tree
+diff :: forall a. (Transform a) => a -> a -> Transformation a
+diff a b = evalState (build False a b) Map.empty
+  where
+    childPaths :: [(a,Path)]
+    childPaths = childrenPaths a
+    buildmem :: Bool -> a -> a -> State (Memo a) (Transformation a)
+    buildmem a b c = do
+      mp <- get
+      let k = MemoKey a b c
+      case Map.lookup k mp of
+        Just r  -> return r
+        Nothing -> do
+          r <- build a b c
+          modify (Map.insert k r)
+          return r
+    build :: Bool -> a -> a -> State (Memo a) (Transformation a)
+    build False a' b' | GEq.eq a' b' = return []
+    build ins a' b' = case lookupWith GEq.eq b' childPaths of
+      Just p  -> return [([], In (Ref p))]
+      Nothing -> uses >>= maybe insert return
+        where
+          -- Construct the edits for the children based on a root
+          construct :: Bool -> a -> State (Memo a) (Maybe (Transformation a))
+          construct ins' c =
+            if shallowEq (from c) (from b')
+            then do r <- zipWithM (buildmem ins') (imChildren c) (imChildren b')
+                    return $ Just $ concat $ updateChildPaths r
+            else return Nothing
+          -- Possible edits reusing the existing tree or using a part of
+          -- the original tree. The existing tree is only used if we didn't
+          -- just insert it, since we want to keep the inserts small
+          uses :: State (Memo a) (Maybe (Transformation a))
+          uses = reuses >>= \re -> case re of
+              Just r | ins -> return re
+              _            -> construct ins a' >>= return . best re
+          -- Possible edits that include reusing a part of the original tree
+          reuses :: State (Memo a) (Maybe (Transformation a))
+          reuses = foldM f Nothing childPaths where
+            addRef p = fmap (([], In (Ref p)):)
+            f c (x,p) = construct False x >>= return . best c . addRef p
+          -- Best edit including insertion, only chosen if nothing can be reused
+          insert :: State (Memo a) (Transformation a)
+          insert = do
+            Just r <- construct True b'
+            let (r', e') = partialApply (withRefs b') r
+            return $ ([], r') : e'
+
+-- | Helper function for lookup with provided compare function
+lookupWith :: (a -> a -> Bool) -> a -> [(a,b)] -> Maybe b
+lookupWith _ _ [] = Nothing
+lookupWith f a ((b,r):bs)
+  | f a b     = Just r
+  | otherwise = lookupWith f a bs
+
+-- | Pick the best edit
+best :: Maybe (Transformation a) -> Maybe (Transformation a) -> Maybe (Transformation a)
+best e1 e2 = case (e1,e2) of
+  (Just e1', Just e2') -> Just (pickShortest e1' e2')
+  _                    -> e1 <|> e2
+
+-- | Pick the shortest of two lists lazily
+pickShortest :: [a] -> [a] -> [a]
+pickShortest a b = if f a b then a else b
+  where f []     _      = True
+        f _      []     = False
+        f (_:xs) (_:ys) = f xs ys
+
+-- | Lift a tree to a tree with references
+withRefs :: Transform a => a -> Fix (WithRef a)
+withRefs = In . InR . fmap withRefs . from
+
+-- | Try to apply as much edits to the edit structure as possible
+--   to make the final edit smaller
+partialApply :: Transform a =>
+                Fix (WithRef a) -> Transformation a -> (Fix (WithRef a), Transformation a)
+partialApply a [] = (a, [])
+partialApply a ((p,r):xs) = case replace p r a of
+  Just a' -> partialApply a' xs
+  Nothing -> let (a',xs') = partialApply a xs in (a', (p,r) : xs')
+
+-- | Replace a subtree in an edit structure
+replace :: (Transform a, Monad m)
+           => Path -> Fix (WithRef a) -> Fix (WithRef a) -> m (Fix (WithRef a))
+replace []     r _ = return r
+replace (i:is) r a = case a of
+  In (Ref _) -> fail "Replace"
+  In (InR a') -> tmapN f a' >>= return . In . InR
+    where f j = if i == j then replace is r else return
+
+-- | Extend the paths of edits for the children with the child number
+updateChildPaths :: [Transformation a] -> [Transformation a]
+updateChildPaths = zipWith (\n -> map (\(p,c) -> (n:p,c))) [0..]
+
+--------------------------------------------------------------------------------
+-- Shallow equality
+--------------------------------------------------------------------------------
+
+class SEq f where
+  shallowEq :: f a -> f a -> Bool
+
+instance SEq I where
+  shallowEq (I _) (I _) = True
+
+instance SEq U where
+  shallowEq U U = True
+
+instance Eq a => SEq (K a) where
+  shallowEq (K a) (K b) = a == b
+
+instance (SEq f, SEq g) => SEq (f :+: g) where
+  shallowEq (L a) (L b) = shallowEq a b
+  shallowEq (R a) (R b) = shallowEq a b
+  shallowEq _     _     = False
+
+instance (SEq f, SEq g) => SEq (f :*: g) where
+  shallowEq (a :*: b) (c :*: d) = shallowEq a c && shallowEq b d
+
+instance SEq f => SEq (C c f) where
+  shallowEq (C a) (C b) = shallowEq a b
+
+instance SEq f => SEq (S s f) where
+  shallowEq (S a) (S b) = shallowEq a b
+
+--------------------------------------------------------------------------------
+-- ExtractN
+--------------------------------------------------------------------------------
+
+class ExtractN f where
+  extractN :: Monad m => Int -> f a -> m a
+
+instance ExtractN I where
+  extractN 0 (I r) = return r
+  extractN _ (I _) = fail "extractN"
+
+instance ExtractN (K a) where
+  extractN _ (K _) = fail "extractN"
+
+instance ExtractN U where
+  extractN _ U = fail "extractN"
+
+instance (ExtractN f, ExtractN g) => ExtractN (f :+: g) where
+  extractN i (L x) = extractN i x
+  extractN i (R x) = extractN i x
+
+-- Here we decrement our parameter. Does not require right-nested products
+instance (CountI f, ExtractN f, ExtractN g) => ExtractN (f :*: g) where
+  extractN i (x :*: y) = let n = countI x
+                          in if i < n then extractN i     x
+                                      else extractN (i-n) y
+
+instance ExtractN f => ExtractN (C c f) where
+  extractN i (C x) = extractN i x
+
+instance ExtractN f => ExtractN (S s f) where
+  extractN i (S x) = extractN i x
+
+--------------------------------------------------------------------------------
+-- MapN
+--------------------------------------------------------------------------------
+
+-- | Map a function with child index at a top-level structure
+tmapN :: (Monad m, MapN f) => (Int -> a -> m b) -> f a -> m (f b)
+tmapN = mapN 0
+
+class MapN f where
+  mapN :: Monad m => Int -> (Int -> a -> m b) -> f a -> m (f b)
+
+instance MapN I where
+  mapN i f (I r) = liftM I (f i r)
+
+instance MapN (K a) where
+  mapN _ _ (K x)  = liftM K (return x)
+
+instance MapN U where
+  mapN _ _ U = return U
+
+instance (MapN f, MapN g) => MapN (f :+: g) where
+  mapN i f (L x) = liftM L (mapN i f x)
+  mapN i f (R x) = liftM R (mapN i f x)
+
+-- Here we increment our parameter. Does not require right-nested products
+instance (CountI f, MapN f, MapN g) => MapN (f :*: g) where
+  mapN i f (x :*: y) = liftM2 (:*:) (mapN i f x) (mapN (i + countI x) f y)
+
+instance MapN f => MapN (C c f) where
+  mapN i f (C x) = liftM C (mapN i f x)
+
+instance MapN f => MapN (S s f) where
+  mapN i f (S x) = liftM S (mapN i f x)
+
+
+--------------------------------------------------------------------------------
+-- CountI
+--------------------------------------------------------------------------------
+
+class CountI f where
+  -- | Count the number of recursive occurrences
+  countI :: f a -> Int
+
+instance CountI I where
+  countI _ = 1
+
+instance CountI (K a) where
+  countI _ = 0
+
+instance CountI U where
+  countI _ = 0
+
+instance (CountI f, CountI g) => CountI (f :+: g) where
+  countI (L x) = countI x
+  countI (R x) = countI x
+
+instance (CountI f, CountI g) => CountI (f :*: g) where
+  countI (x :*: y) = countI x + countI y
+
+instance CountI f => CountI (C c f) where
+  countI (C x) = countI x
+
+instance CountI f => CountI (S s f) where
+  countI (S x) = countI x
+
+--------------------------------------------------------------------------------
+-- Children
+--------------------------------------------------------------------------------
+
+-- | Get the immediate children
+imChildren :: (Regular a, Children (PF a)) => a -> [a]
+imChildren = children . from
+
+-- | Get all children with their paths
+childrenPaths :: (Regular a, Children (PF a)) => a -> [(a,Path)]
+childrenPaths a = (a, []) : [ (r, n : p)
+                            | (n, c) <- zip [0..] (imChildren a)
+                            , (r, p) <- childrenPaths c ]
+
+class Children f where
+  children :: f a -> [a]
+
+instance Children I where
+  children (I r) = [r]
+
+instance Children (K a) where
+  children (K _) = []
+
+instance Children U where
+  children U = []
+
+instance (Children f, Children g) => Children (f :+: g) where
+  children (L x) = children x
+  children (R x) = children x
+
+instance (Children f, Children g) => Children (f :*: g) where
+  children (x :*: y) = children x ++ children y
+
+instance Children f => Children (C c f) where
+  children (C x) = children x
+
+instance Children f => Children (S s f) where
+  children (S x) = children x
+ Generics/Regular/Transformations/RewriteRules.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+
+module Generics.Regular.Transformations.RewriteRules (
+  Transform, Transformation, apply
+  ) where
+
+import Generics.Regular
+import Generics.Regular.Rewriting
+import Generics.Regular.Zipper
+
+import Control.Monad ( foldM )
+
+--------------------------------------------------------------------------------
+-- Patch
+--------------------------------------------------------------------------------
+-- Basically, a class synonym
+class (Regular a, Rewrite a, Zipper (PF a)) => Transform a
+instance Transform a => Rewrite a
+
+-- An edit is a list of:
+type Transformation a = [ ( Loc a -> Maybe (Loc a) -- A path to the location to edit
+                          , Rule a) ]              -- The rewrite rule to apply there
+
+-- Patching is terribly simple: at the given locations, apply all the rules,
+-- then exit the zipper.
+apply :: forall a. (Transform a) => Transformation a -> a -> Maybe a
+apply rs = fmap leave . flip (foldM appRule) rs . enter
+  where appRule a (l,r) = l a >>= updateM (rewriteM r)
+ Generics/Regular/Transformations/ZipperState.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE FlexibleContexts           #-}
+
+module Generics.Regular.Transformations.ZipperState (
+  ZipperMonad, ZipperState, upMonad, downMonad, leftMonad, rightMonad, 
+  navigate, saveMonad, loadMonad, topMonad, updateMonad
+  ) where
+
+import Control.Monad.State (StateT (..), evalStateT, get, put)
+
+import Generics.Regular.Zipper
+import Generics.Regular ( Regular, PF )
+
+--------------------------------------------------------------------------------
+-- A zipper with state
+--------------------------------------------------------------------------------
+
+type ZipperState a = ([a], Loc a)
+type ZipperMonad a b = StateT (ZipperState a) Maybe b
+
+moveMonad :: (Loc a -> Maybe (Loc a)) -> ZipperMonad a a
+moveMonad m = StateT (\(s,l) -> m l >>= (\l' -> return (on l', (s,l'))))
+
+upMonad, downMonad, leftMonad, rightMonad :: ZipperMonad a a
+upMonad    = moveMonad up
+downMonad  = moveMonad down
+leftMonad  = moveMonad left
+rightMonad = moveMonad right
+
+updateMonad :: (a -> a) -> ZipperMonad a a
+updateMonad f = do (s,l) <- get
+                   let l' = update f l
+                   put (s,l')
+                   return (on l')
+
+saveMonad :: ZipperMonad a a
+saveMonad = do (s,l) <- get
+               let a = on l
+               put (s++[a],l)
+               return a
+
+loadMonad :: ZipperMonad a a
+loadMonad = do (s:ss,l) <- get
+               let l' = update (const s) l
+               put (ss,l')
+               return (on l')
+
+topMonad :: ZipperMonad a a
+topMonad = do (_, Loc x l) <- get
+              case l of
+                [] -> return x
+                _  -> upMonad >> topMonad
+
+leaveMonad :: Loc a -> ZipperMonad a b -> Maybe a
+leaveMonad s m = evalStateT (m >> topMonad) ([],s)
+
+navigate :: (Regular a, Zipper (PF a)) => a -> ZipperMonad a b -> Maybe a
+navigate x m = leaveMonad (enter x) m
+ Generics/Regular/Zipper.hs view
@@ -0,0 +1,245 @@+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE GADTs                      #-}
+{-# LANGUAGE KindSignatures             #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE RankNTypes                 #-}
+{-# LANGUAGE TypeFamilies               #-}
+{-# LANGUAGE TypeOperators              #-}
+{-# LANGUAGE EmptyDataDecls             #-}
+{-# LANGUAGE TupleSections              #-}
+
+module Generics.Regular.Zipper
+  (-- * Locations
+   Loc(..),
+   -- * Context frames
+   Ctx(),
+   -- * Generic zipper class
+   Zipper(..),
+   -- * Interface
+   enter,
+   down, down', up, right, left,
+   -- dfnext, dfprev,
+   leave, on, update, updateM
+
+  )
+  where
+
+import Prelude hiding (last)
+
+import Control.Monad
+import Control.Monad.State
+import Control.Applicative
+import Data.Maybe
+import Data.Traversable
+
+import Generics.Regular hiding (left, right)
+
+-- * Locations and context stacks
+
+-- | Abstract type of locations. A location contains the current focus
+-- and its context. A location is parameterized over the family of
+-- datatypes and over the type of the complete value.
+
+data Loc :: * -> * where
+  Loc :: (Regular a, Zipper (PF a)) => a -> [Ctx (PF a) a] -> Loc a
+
+-- * Context frames
+
+-- | Abstract type of context frames. Not required for the high-level
+-- navigation functions.
+
+data family Ctx (f :: * -> *) :: * -> *
+
+data instance Ctx (K a) r
+data instance Ctx U r
+data instance Ctx (f :+: g) r = CL (Ctx f r) | CR (Ctx g r)
+data instance Ctx (f :*: g) r = C1 (Ctx f r) (g r) | C2 (f r) (Ctx g r)
+data instance Ctx I r = CId
+data instance Ctx (C c f) r = CC (Ctx f r)
+data instance Ctx (S s f) r = CS (Ctx f r)
+
+-- * Contexts and locations are functors
+
+instance Zipper f => Functor (Ctx f) where
+  fmap = cmap
+
+-- instance Functor (Loc f) where
+  -- fmap f (Loc p x)  = Loc (f p) (map (fmap f) x)
+
+-- * Generic navigation functions
+
+-- | It is in general not necessary to use the generic navigation
+-- functions directly. The functions listed in the ``Interface'' section
+-- below are more user-friendly.
+--
+
+class Functor f => Zipper f where
+  cmap        :: (a -> b) -> Ctx f a -> Ctx f b
+  fill        :: Ctx f a -> a -> f a
+  first, last :: f a -> Maybe (a, Ctx f a)
+  next, prev  :: Ctx f a -> a -> Maybe (a, Ctx f a)
+
+instance Zipper I where
+  cmap  f CId = CId
+  fill  CId x = I x
+  first (I x) = Just (x, CId)
+  last  (I x) = Just (x, CId)
+  next  CId x = Nothing
+  prev  CId x = Nothing
+
+instance Zipper (K a) where
+  cmap f void = impossible void
+  fill void x = impossible void
+  first (K a) = Nothing
+  last  (K a) = Nothing
+  next  void x = impossible void
+  prev  void x = impossible void
+
+instance Zipper U where
+  cmap f void = impossible void
+  fill void x = impossible void
+  first U      = Nothing
+  last  U      = Nothing
+  next  void x = impossible void
+  prev  void x = impossible void
+
+instance (Zipper f, Zipper g) => Zipper (f :+: g) where
+  cmap f (CL c)   = CL (cmap f c)
+  cmap f (CR c)   = CR (cmap f c)
+  fill (CL c) x   = L (fill c x)
+  fill (CR c) y   = R (fill c y)
+  first (L x)     = first x >>= return . fmap CL
+  first (R x)     = first x >>= return . fmap CR
+  last  (L x)     = last x >>= return . fmap CL
+  last  (R x)     = last x >>= return . fmap CR
+  next  (CL c) x = next c x >>= return . fmap CL
+  next  (CR c) x = next c x >>= return . fmap CR
+  prev  (CL c) x = prev c x >>= return . fmap CL
+  prev  (CR c) x = prev c x >>= return . fmap CR
+
+instance (Zipper f, Zipper g) => Zipper (f :*: g) where
+  cmap f (C1 c y)   = C1 (cmap f c) (fmap f y)
+  cmap f (C2 x c)   = C2 (fmap f x) (cmap f c)
+  fill (C1 c y) x = fill c x :*: y
+  fill (C2 x c) y = x :*: fill c y
+  first (x :*: y) =         fmap (fmap (flip C1 y)) (first x)
+                    `mplus` fmap (fmap (C2 x))      (first y)
+  last  (x :*: y) =         fmap (fmap (C2 x))      (last  y)
+                    `mplus` fmap (fmap (flip C1 y)) (last  x)
+  next (C1 c y) z =         (fmap (flip C1 y)     <$> next c z)
+                    `mplus` (fmap (C2 (fill c z)) <$> first y)
+  next (C2 x c) z =          fmap (C2 x)          <$> next c z
+  prev (C1 c y) z =          fmap (flip C1 y)     <$> prev c z
+  prev (C2 x c) z =         (fmap (C2 x)               <$> prev c z)
+                    `mplus` (fmap (flip C1 (fill c z)) <$> last x)
+
+instance (Zipper f) => Zipper (C c f) where
+  cmap f (CC c)   = CC (cmap f c)
+  fill   (CC c) x = C (fill c x)
+  first  (C x)    = first  x >>= return . fmap CC
+  last   (C x)    = last   x >>= return . fmap CC
+  next   (CC c) x = next c x >>= return . fmap CC
+  prev   (CC c) x = prev c x >>= return . fmap CC
+
+instance (Zipper f) => Zipper (S s f) where
+  cmap f (CS c)   = CS (cmap f c)
+  fill   (CS c) x = S (fill c x)
+  first  (S x)    = first  x >>= return . fmap CS
+  last   (S x)    = last   x >>= return . fmap CS
+  next   (CS c) x = next c x >>= return . fmap CS
+  prev   (CS c) x = prev c x >>= return . fmap CS
+
+-- * Interface
+
+-- ** Introduction
+
+-- | Start navigating a datastructure. Returns a location that
+-- focuses the entire value and has an empty context.
+enter :: (Regular a, Zipper (PF a)) => a -> Loc a
+enter x = Loc x []
+
+-- ** Navigation
+
+-- | Move down to the leftmost child. Returns 'Nothing' if the
+-- current focus is a leaf.
+down :: Loc a -> Maybe (Loc a)
+down (Loc x cs) = first (from x) >>= \(a,c) -> return (Loc a (c:cs))
+
+-- | Move down to the rightmost child. Returns 'Nothing' if the
+-- current focus is a leaf.
+down' :: Loc a -> Maybe (Loc a)
+down' (Loc x cs) = last (from x) >>= \(a,c) -> return (Loc a (c:cs))
+
+-- | Move up to the parent. Returns 'Nothing' if the current
+-- focus is the root.
+up :: Loc a -> Maybe (Loc a)
+up (Loc x [])     = Nothing
+up (Loc x (c:cs)) = return (Loc (to (fill c x)) cs)
+
+-- | Move to the right sibling. Returns 'Nothing' if the current
+-- focus is the rightmost sibling.
+right :: Loc a -> Maybe (Loc a)
+right (Loc x []    ) = Nothing
+right (Loc x (c:cs)) = next c x >>= \(a,c') -> return (Loc a (c':cs))
+
+-- | Move to the left sibling. Returns 'Nothing' if the current
+-- focus is the leftmost sibling.
+left :: Loc a -> Maybe (Loc a)
+left (Loc x []    ) = Nothing
+left (Loc x (c:cs)) = prev c x >>= \(a,c') -> return (Loc a (c':cs))
+
+
+-- ** Derived navigation.
+{-
+df :: (a -> Maybe a) -> (a -> Maybe a) -> (a -> Maybe a) -> a -> Maybe a
+df d u lr l =
+  case d l of
+    Nothing -> df' l
+    r       -> r
+ where
+  df' l =
+    case lr l of
+      Nothing -> case u l of
+                   Nothing -> Nothing
+                   Just l' -> df' l'
+      r       -> r
+
+-- | Move through all positions in depth-first left-to-right order.
+dfnext :: Loc phi I0 ix -> Maybe (Loc phi I0 ix)
+dfnext = df down up right
+
+-- | Move through all positions in depth-first right-to-left order.
+dfprev :: Loc phi I0 ix -> Maybe (Loc phi I0 ix)
+dfprev = df down' up left
+-}
+
+-- | Utility
+-- navigate :: (Regular a, Zipper (PF a))
+         -- => a -> (Loc a -> Maybe (Loc a)) -> Loc a
+-- navigate a f = fromJust $ f (enter a)
+
+-- ** Elimination
+
+-- | Return the entire value, independent of the current focus.
+leave :: Loc a -> a
+leave (Loc x []) = x
+leave loc        = leave (fromJust (up loc))
+
+-- | Operate on the current focus. This function can be used to
+-- extract the current point of focus.
+on :: Loc a -> a
+on (Loc x _) = x
+
+-- | Update the current focus without changing its type.
+update :: (a -> a) -> Loc a -> Loc a
+update f (Loc x cs) = Loc (f x) cs
+
+-- | Update the current focus without changing its type.
+updateM :: Monad m => (a -> m a) -> Loc a -> m (Loc a)
+updateM f (Loc x cs) = f x >>= \y -> return (Loc y cs)
+
+-- * Internal functions
+
+impossible :: a -> b
+impossible x = x `seq` error "impossible"
+ LICENSE view
@@ -0,0 +1,675 @@+              GNU GENERAL PUBLIC LICENSE
+                Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                     Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+ 
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+  
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+              END OF TERMS AND CONDITIONS
+
+     How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple
+main = defaultMain
+ examples/Datatypes.hs view
@@ -0,0 +1,81 @@+
+module Datatypes (
+  Tree (..), exTree1, exTree2, exTree3, exTree4, exTree5,
+  List (..), toL, fromL, exLst1, exLst2,
+  X (..), exX1, exX2,
+  Zig (..), Zag (..), zigzag, zigzag2,
+  Expr, prog1, prog2, prog3, prog4, prog5, prog6,
+  module Lang
+  ) where
+
+import Lang
+import Data.List ( unfoldr )
+
+--------------------------------------------------------------------------------
+-- Example datatypes
+--------------------------------------------------------------------------------
+
+--Trees
+data Tree = Leaf Int | Bin Tree Tree deriving (Show, Eq)
+
+exTree1, exTree2, exTree3, exTree4, exTree5 :: Tree
+exTree1 = Bin (Leaf 0) (Leaf 1)
+exTree2 = Bin (Leaf 1) (Leaf 0)
+exTree3 = Bin (Leaf 2) (Leaf 3)
+exTree4 = Bin exTree2 exTree3
+exTree5 = Bin exTree3 exTree4
+
+-- Lists
+data List a = Nil | Cons a (List a) deriving (Eq, Show)
+
+toL :: [a] -> List a
+toL = foldr Cons Nil
+
+fromL :: List a -> [a]
+fromL = unfoldr f where
+  f Nil        = Nothing
+  f (Cons h t) = Just (h,t)
+
+exLst1, exLst2 :: List Int
+exLst1 = Cons 1 $ Cons 2 $ Cons 3 $ Cons 4 Nil
+exLst2 = Cons 4 $ Cons 2 $ Cons 3 $ Cons 1 Nil
+
+-- Something more exotic
+data X = XA X | XB X | XC X X | XD Int deriving (Show, Eq)
+
+exX1, exX2 :: X
+exX1 = XA (XA (XA (XC (XD 1) (XD 2))))
+exX2 = XA (XB (XA (XA (XB (XC (XD 2) (XD 1))))))
+
+-- Mutually recursive
+data Zig = Zig1 Zig | Zig2 Zag | Zig3 deriving (Show, Eq)
+data Zag = Zag1 Zag | Zag2 Zig | Zag3 deriving (Show, Eq)
+
+zigzag :: Zig
+zigzag = Zig1 (Zig2 (Zag2 Zig3))
+
+zigzag2 :: Zig
+zigzag2 = Zig2 (Zag1 (Zag2 Zig3))
+
+-- Example from paper (imported from Lang)
+type Expr = AExpr
+
+progFragment1, progFragment2 :: String
+progFragment1 =     "a := 1;"
+                 ++ "b := a + 2;"
+                 ++ "if b > 3"
+                 ++ "then a := 2"
+                 ++ "else b := 1;"
+progFragment2 =     "a := 1;"
+                 ++ "b := a + 2;"
+                 ++ "if not b > 3"
+                 ++ "then b := 1"
+                 ++ "else a := 2;"
+
+prog1, prog2, prog3, prog4, prog5, prog6 :: Stmt
+prog1 = parseString . init . concat . replicate 1 $ progFragment1
+prog2 = parseString . init . concat . replicate 1 $ progFragment2
+prog3 = parseString . init . concat . replicate 4 $ progFragment1
+prog4 = parseString . init . concat . replicate 4 $ progFragment2
+prog5 = parseString . init . concat . replicate 5 $ progFragment1
+prog6 = parseString . init . concat . replicate 5 $ progFragment2
+ examples/Lang.lhs view
@@ -0,0 +1,368 @@+Source: http://www.haskell.org/haskellwiki/Parsing_a_simple_imperative_language
+
+This tutorial will present how to parse a subset of a simple imperative
+programming language called W<small>HILE</small> (introduced in a book
+"Principles of Program Analysis" by Nielson, Nielson and Hankin). It includes
+only a few statements and basic boolean/arithmetic expressions, which makes it
+a nice material for a tutorial.
+
+== Imports ==
+
+First let's specify the name of the module:
+
+<haskell>
+
+> module Lang where
+
+</haskell>
+
+And then import the necessary libraries:
+
+<haskell>
+
+> import System.IO
+> import Control.Monad
+> import Text.ParserCombinators.Parsec
+> import Text.ParserCombinators.Parsec.Expr
+> import Text.ParserCombinators.Parsec.Language
+> import qualified Text.ParserCombinators.Parsec.Token as Token
+
+</haskell>
+
+== The language ==
+
+The grammar for expressions is defined as follows:
+
+<tt>
+
+''a''   ::=  ''x'' | ''n'' | - ''a'' | ''a'' ''opa'' ''a''
+
+''b''   ::=  true | false | not ''b'' | ''b'' ''opb'' ''b'' | ''a'' ''opr'' ''a''
+
+''opa'' ::=  + | - | * | /
+
+''opb'' ::=  and | or
+
+''opr'' ::=  > | <
+
+</tt>
+
+Note that we have three groups of operators - arithmetic, booloan and
+relational ones.
+
+And now the definition of statements:
+
+<tt>
+
+''S''   ::=  x := ''a'' | skip | ''S1''; ''S2'' | ''( S )'' | if ''b'' then ''S1'' else ''S2'' | while ''b'' do ''S''
+
+</tt>
+
+We probably want to parse that into some internal representation of the
+language (abstract syntax tree). Therefore we need to define the data
+structures for the expressions and statements.
+
+== Data structures ==
+
+We need to take care of boolean and arithmetic expressions and the
+appropriate operators. First let's look at the boolean expressions:
+
+<haskell>
+
+> data BExpr = BConst Bool
+>            | Not BExpr
+>            | And BExpr BExpr
+>            | Greater AExpr AExpr
+>             deriving (Show, Eq)
+
+</haskell>
+
+Now we define the types for arithmetic expressions:
+
+<haskell>
+
+> data AExpr = Var String
+>            | Const Integer
+>            | Neg AExpr
+>            | Add AExpr AExpr
+>              deriving (Show, Eq)
+
+</haskell>
+
+Finally let's take care of the statements:
+
+<haskell>
+
+> data Stmt = Seq [Stmt]
+>           | Assign String AExpr
+>           | If BExpr Stmt Stmt
+>           | While BExpr Stmt
+>           | Skip
+>             deriving (Show, Eq)
+
+</haskell>
+
+== Lexer ==
+
+Having all the data structures we can go on with writing the code to do actual
+parsing. First of all we create the language definition using Haskell's record
+syntax and the constructor <hask>emptyDef</hask> (from
+<hask>Text.ParserCombinators.Parsec.Language</hask>):
+
+<haskell>
+
+> languageDef =
+>   emptyDef { Token.commentStart    = "/*"
+>            , Token.commentEnd      = "*/"
+>            , Token.commentLine     = "//"
+>            , Token.identStart      = letter
+>            , Token.identLetter     = alphaNum
+>            , Token.reservedNames   = [ "if"
+>                                      , "then"
+>                                      , "else"
+>                                      , "while"
+>                                      , "do"
+>                                      , "skip"
+>                                      , "true"
+>                                      , "false"
+>                                      , "not"
+>                                      , "and"
+>                                      , "or"
+>                                      ]
+>            , Token.reservedOpNames = ["+", "-", "*", "/", ":="
+>                                      , "<", ">", "and", "or", "not"
+>                                      ]
+>            }
+
+</haskell>
+
+This creates a language definition that accepts the C-style comments, requires
+that the identifiers start with a letter, and end with alphanumeric
+characters. Moreover there is a number of reserved names, that cannot be used
+by the identifiers.
+
+Having the above definition we can create a lexer:
+
+<haskell>
+
+> lexer = Token.makeTokenParser languageDef
+
+</haskell>
+
+<tt>lexer</tt> contains a number of lexical parsers, that we can us to parse
+identifiers, reserved words/operations, etc. Now we can select/extract them in
+the following way:
+
+<haskell>
+
+> identifier = Token.identifier lexer -- parses an identifier
+> reserved   = Token.reserved   lexer -- parses a reserved name
+> reservedOp = Token.reservedOp lexer -- parses an operator
+> parens     = Token.parens     lexer -- parses surrounding parenthesis:
+>                                     --   parens p
+>                                     -- takes care of the parenthesis and
+>                                     -- uses p to parse what's inside them
+> integer    = Token.integer    lexer -- parses an integer
+> semi       = Token.semi       lexer -- parses a semicolon
+> whiteSpace = Token.whiteSpace lexer -- parses whitespace
+
+</haskell>
+
+This isn't really necessary, but should make the code much more readable (also
+this is the reason why we used the qualified import of
+<hask>Text.ParserCombinators.Parsec.Token</hask>). Now we can use them to
+parse the source code at the token level. One of the nice features of these
+parsers is that they take care of all whitespace after the tokens.
+
+== Main parser ==
+
+As already mentioned a program in this language is simply a statement, so the
+main parser should basically only parse a statement. But remember to take care of
+initial whitespace - our parsers only get rid of whitespace after the tokens!
+
+<haskell>
+
+> whileParser :: Parser Stmt
+> whileParser = whiteSpace >> statement
+
+</haskell>
+
+Now because any statement might be actually a sequence of statements separated
+by semicolon, we use <hask>sepBy1</hask> to parse at least one statement. The
+result is a list of statements. We also allow grouping statements by the
+parenthesis, which is useful, for instance, in the <tt>while</tt> loop.
+
+<haskell>
+
+> statement :: Parser Stmt
+> statement =   parens statement
+>           <|> sequenceOfStmt
+
+> sequenceOfStmt =
+>   do list <- (sepBy1 statement' semi)
+>      -- If there's only one statement return it without using Seq.
+>      return $ if length list == 1 then head list else Seq list
+
+</haskell>
+
+Now a single statement is quite simple, it's either an if conditional, a while
+loop, an assignment or simply a skip statement. We use <hask><|></hask> to
+express choice. So <hask>a <|> b</hask> will first try parser <hask>a</hask>
+and if it fails (but without actually consuming any input) then parser
+<hask>b</hask> will be used. Note: this means that the order is important.
+
+<haskell>
+
+> statement' :: Parser Stmt
+> statement' =   ifStmt
+>            <|> whileStmt
+>            <|> skipStmt
+>            <|> assignStmt
+
+</haskell>
+
+If you have a parser that might fail after consuming some input, and you still
+want to try the next parser, you should look into <hask>try</hask> combinator.
+For instance <hask>try p <|> q</hask> will try parsing with <hask>p</hask> and
+if it fails, even after consuming the input, the <hask>q</hask> parser will be
+used as if nothing has been consumed by <hask>p</hask>.
+
+Now let's define the parsers for all the possible statements. This is quite
+straightforward as we just use the parsers from the lexer and then use all the
+necessary information to create appropriate data structures.
+
+<haskell>
+
+> ifStmt :: Parser Stmt
+> ifStmt =
+>   do reserved "if"
+>      cond  <- bExpression
+>      reserved "then"
+>      stmt1 <- statement
+>      reserved "else"
+>      stmt2 <- statement
+>      return $ If cond stmt1 stmt2
+
+> whileStmt :: Parser Stmt
+> whileStmt =
+>   do reserved "while"
+>      cond <- bExpression
+>      reserved "do"
+>      stmt <- statement
+>      return $ While cond stmt
+
+> assignStmt :: Parser Stmt
+> assignStmt =
+>   do var  <- identifier
+>      reservedOp ":="
+>      expr <- aExpression
+>      return $ Assign var expr
+
+> skipStmt :: Parser Stmt
+> skipStmt = reserved "skip" >> return Skip
+
+</haskell>
+
+== Expressions ==
+
+What's left is to parse the expressions. Fortunately Parsec provides a very
+easy way to do that. Let's define the arithmetic and boolean expressions:
+
+<haskell>
+
+> aExpression :: Parser AExpr
+> aExpression = buildExpressionParser aOperators aTerm
+
+> bExpression :: Parser BExpr
+> bExpression = buildExpressionParser bOperators bTerm
+
+</haskell>
+
+Now we have to define the lists with operator precedence, associativity and
+what constructors to use in each case.
+
+<haskell>
+
+> aOperators = [ [Prefix (reservedOp "-"   >> return (Neg             ))          ]
+>              , [Infix  (reservedOp "+"   >> return (Add             )) AssocLeft]
+>               ]
+
+> bOperators = [ [Prefix (reservedOp "not" >> return (Not             ))          ]
+>              , [Infix  (reservedOp "and" >> return (And             )) AssocLeft]
+>              ]
+
+</haskell>
+
+In case of Prefix operators it is enough to specify which one should be parsed
+and what is the associated data constructor. Infix operators are defined
+similarly, but it's necessary to add information about associativity. Note
+that the operator precedence depends only on the order of the elements in the
+list.
+
+Finally we have to define the terms. In case of arithmetic expressions, it is
+quite simple:
+
+<haskell>
+
+> aTerm =  parens aExpression
+>      <|> liftM Var identifier
+>      <|> liftM Const integer
+
+</haskell>
+
+However, the term in a boolean expression is a bit more tricky. In this case,
+a term can also be an expression with relational operator consisting of
+arithmetic expressions.
+
+<haskell>
+
+> bTerm =  parens bExpression
+>      <|> (reserved "true"  >> return (BConst True ))
+>      <|> (reserved "false" >> return (BConst False))
+>      <|> rExpression
+
+</haskell>
+
+Therefore we have to define a parser for relational expressions:
+
+<haskell>
+
+> rExpression =
+>   do a1 <- aExpression
+>      op <- reservedOp ">"
+>      a2 <- aExpression
+>      return $ Greater a1 a2
+
+</haskell>
+
+And that's it. We have a quite simple parser able to parse a few statements and
+arithmetic/boolean expressions.
+
+== Notes ==
+
+If you want to experiment with the parser inside ghci, these functions might be
+handy:
+
+<haskell>
+
+> parseString :: String -> Stmt
+> parseString str =
+>   case parse whileParser "" str of
+>     Left e  -> error $ show e
+>     Right r -> r
+
+> parseFile :: String -> IO Stmt
+> parseFile file =
+>   do program  <- readFile file
+>      case parse whileParser "" program of
+>        Left e  -> print e >> fail "parse error"
+>        Right r -> return r
+
+</haskell>
+
+Now you can simply load the module in ghci and then do
+<hask>ast <- parseFile "<filename>"</hask> to parse a file and get the
+result if parsing was successful. If you already have a string with
+the program, you can use <hask>parseString</hask>.
+
+[[Category:How to]]
+ examples/MultiRec.hs view
@@ -0,0 +1,177 @@+{-# LANGUAGE GADTs                 #-}
+{-# LANGUAGE KindSignatures        #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE TypeSynonymInstances  #-}
+{-# LANGUAGE EmptyDataDecls        #-}
+{-# LANGUAGE TemplateHaskell       #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE DataKinds             #-}
+{-# LANGUAGE PolyKinds             #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module MultiRec where
+
+import Datatypes
+import Generics.MultiRec.Any
+import Generics.MultiRec.Transformations.RewriteRules as RR
+import Generics.MultiRec.Transformations.ZipperState
+import Generics.MultiRec.Transformations.Explicit as Ex
+import Generics.MultiRec.Rewriting
+import Generics.MultiRec.Zipper
+
+import Generics.MultiRec hiding (show)
+import Generics.MultiRec.TH
+
+import Control.Monad ( (>=>) )
+
+--------------------------------------------------------------------------------
+-- Multirec representations for the example datatypes
+--------------------------------------------------------------------------------
+data TreeAST :: * -> * where
+  Tree :: TreeAST Tree
+
+$(deriveAll ''TreeAST)
+
+data ListAST :: * -> * -> * where
+  List :: ListAST a (List a)
+
+$(deriveAll ''ListAST)
+
+data XAST :: * -> * where
+  X :: XAST X
+
+$(deriveAll ''XAST)
+
+data ZigZag :: * -> * where
+  Zig :: ZigZag Zig
+  Zag :: ZigZag Zag
+
+$(deriveAll ''ZigZag)
+
+data AST i where
+  BExpr  :: AST BExpr
+  AExpr  :: AST AExpr
+  Stmt   :: AST Stmt
+
+$(deriveAll ''AST)
+
+--------------------------------------------------------------------------------
+-- Rewrite rules solution
+--------------------------------------------------------------------------------
+instance RR.Transform AST
+
+-- Now we can simply do the above transformation in a nice way!
+rr = RR.apply [insert (down >=> right >=> right) change] Stmt prog1 == Just prog2
+  where
+    change = rule $ \e a b -> If e a b :~> If (Not e) b a
+
+-- The same one in two steps, which illustrates that rules can be of different
+-- types
+rr2 = RR.apply [ insert (down >=> right >=> right) swap
+               , insert down addNot] Stmt prog1          == Just prog2
+  where
+    swap   :: Rule AST Stmt
+    swap   = rule $ \e a b -> If e a b :~> If e b a
+    addNot :: Rule AST BExpr
+    addNot = rule $ \e -> e :~> Not e
+
+--------------------------------------------------------------------------------
+-- Zipper with state
+--------------------------------------------------------------------------------
+zs = navigate Stmt prog1 $ do
+  downMonad >> rightMonad >> rightMonad
+  -- Swap
+  l <- downMonad >> rightMonad
+  r <- rightMonad
+  updateMonad (\p _ -> matchAny p l)
+  leftMonad
+  updateMonad (\p _ -> matchAny p r)
+  -- Add the not
+  leftMonad
+  updateMonad (\p e -> case p of
+                  BExpr -> Just (Not e)
+                  _     -> Nothing)
+
+--------------------------------------------------------------------------------
+-- Explicit
+--------------------------------------------------------------------------------
+instance Ex.Transform AST
+
+-- Ordering index of AST as AExpr < BExpr < Stmt
+instance OrdI AST where
+  compareI AExpr AExpr = EQ
+  compareI AExpr _     = LT
+  compareI BExpr AExpr = GT
+  compareI BExpr BExpr = EQ
+  compareI BExpr _     = LT
+  compareI Stmt  Stmt  = EQ
+  compareI Stmt  _     = GT
+
+-- Family with references
+class HasRef phi where
+  type RefRep phi ix
+  toRef   :: phi ix -> HFix (WithRef phi) ix -> RefRep phi ix
+  fromRef :: phi ix -> RefRep phi ix -> HFix (WithRef phi) ix
+
+data NiceInsert phi where
+  NiceInsert :: phi ix -> Path -> RefRep phi ix -> NiceInsert phi
+
+type NiceTransformation phi = [ NiceInsert phi]
+
+toNiceTransformation :: HasRef phi => Ex.Transformation phi -> NiceTransformation phi
+toNiceTransformation = map f
+  where f (Ex.AnyInsert p l x) = NiceInsert p l (toRef p x)
+
+-- Instances for example
+data AExprEH = VarEH String
+             | ConstEH Integer
+             | NegEH AExprEH
+             | AddEH AExprEH AExprEH
+             | AExprRef Path
+           deriving (Show, Eq)
+
+data BExprEH = BConstEH Bool
+             | NotEH BExprEH
+             | AndEH BExprEH BExprEH
+             | GreaterEH AExprEH AExprEH
+             | BExprRef Path
+             deriving (Show, Eq)
+
+data StmtEH = SeqEH [StmtEH]
+            | AssignEH String AExprEH
+            | IfEH BExpr StmtEH StmtEH
+            | WhileEH BExprEH StmtEH
+            | SkipEH
+            | StmtRef Path
+            deriving (Show, Eq)
+
+instance HasRef AST where
+  type RefRep AST AExpr = AExprEH
+  type RefRep AST BExpr = BExprEH
+  type RefRep AST Stmt  = StmtEH
+  
+  -- Not complete, but enough for example below
+  toRef AExpr (HIn (Ref p)) = AExprRef p
+  toRef BExpr (HIn (Ref p)) = BExprRef p
+  toRef BExpr (HIn (InR (L (Tag (R (L (C (I x)))))))) = NotEH (toRef BExpr x)
+  toRef Stmt (HIn (Ref p)) = StmtRef p
+
+  fromRef AExpr (AExprRef p) = HIn (Ref p)
+
+-- Show existentials
+instance Show (NiceInsert AST) where
+  show (NiceInsert AExpr x l) = "NiceInsert AExpr (" ++ show x ++ ") " ++ show l
+  show (NiceInsert BExpr x l) = "NiceInsert BExpr (" ++ show x ++ ") " ++ show l
+  show (NiceInsert Stmt x l)  = "NiceInsert Stmt (" ++ show x ++ ") " ++ show l
+
+-- Actual example
+{- This prints: (note the different reference types here)
+  [ NiceInsert BExpr (NotEH (BExprRef [2,0])) [2,0]
+  , NiceInsert Stmt (StmtRef [2,2]) [2,1]
+  , NiceInsert Stmt (StmtRef [2,1]) [2,2] ]
+-}
+expl1 = print $ toNiceTransformation $ diff Stmt prog1 prog2
+expl2 = print $ toNiceTransformation $ diff Stmt prog3 prog4
+expl3 = print $ toNiceTransformation $ diff Stmt prog5 prog6
+ examples/Regular.hs view
@@ -0,0 +1,212 @@+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeFamilies      #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeOperators     #-}
+{-# LANGUAGE EmptyDataDecls    #-}
+module Regular where
+
+import Datatypes
+import Generics.Regular hiding (right)
+import Generics.Regular.Transformations.Explicit as Ex
+import Generics.Regular.Transformations.RewriteRules as RR
+import Generics.Regular.Zipper
+import Generics.Regular.Transformations.ZipperState
+
+import Control.Monad ( (>=>) )
+import Generics.Regular.Rewriting hiding (left, right)
+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 (do manual instance to avoid C's)
+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
+--------------------------------------------------------------------------------
+-- 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)
+
+instance RR.Transform Expr
+instance Ex.Transform Expr
+
+instance Show (Fix (WithRef Expr)) where
+  show (In (Ref p)) = "Ref " ++ show p
+
+-- Insertion (expr1 => expr2)
+rewriteRulesIns :: Maybe Expr
+rewriteRulesIns = RR.apply [(down >=> right, rule1)] expr1
+  where rule1 :: Rule Expr
+        rule1 = rule $ \x -> x :~> Neg x
+
+zipperStateIns :: Maybe Expr
+zipperStateIns = navigate expr1 $ do
+  downMonad >> rightMonad
+  updateMonad Neg
+
+explicitIns :: Maybe Expr
+explicitIns = Ex.apply addNeg expr1
+  where addNeg :: Ex.Transformation Expr
+        addNeg = [ ([1], In . InR . R . R . L . I . In $ Ref [1]) ]
+
+-- Deletion (expr2 => expr1)
+
+rewriteRulesDel :: Maybe Expr
+rewriteRulesDel = RR.apply [(down >=> right, rule2)] expr2
+  where rule2 :: Rule Expr
+        rule2 = rule $ \x -> Neg x :~> x
+
+zipperStateDel :: Maybe Expr
+zipperStateDel = navigate expr2 $ do
+  r <- downMonad >> rightMonad >> downMonad
+  upMonad
+  updateMonad (const r)
+
+explicitDel :: Maybe Expr
+explicitDel = Ex.apply delNeg expr2
+  where delNeg :: Ex.Transformation Expr
+        delNeg = [ ([1], In (Ref [1,0])) ]
+
+-- Swapping (expr1 => expr3)
+rewriteRulesSwap :: Maybe Expr
+rewriteRulesSwap = RR.apply [(return, rule3)] expr1
+  where rule3 :: Rule Expr
+        rule3 = rule $ \l r -> Add l r :~> Add r l
+
+zipperStateSwap :: Maybe Expr
+zipperStateSwap = navigate expr1 $ do
+  l <- downMonad
+  r <- rightMonad
+  updateMonad (const l)
+  leftMonad
+  updateMonad (const r)
+
+explicitSwap :: Maybe Expr
+explicitSwap = Ex.apply swap' expr1
+  where swap' :: Ex.Transformation Expr
+        swap' = [ ([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
+
+--------------------------------------------------------------------------------
+-- Other RewriteRules examples
+--------------------------------------------------------------------------------
+instance RR.Transform Tree
+instance RR.Transform X
+
+-- Test swapping two subtrees. Note the nice syntax!
+swap :: Rule Tree
+swap = rule $ \t1 t2 -> Bin t1 t2 :~> Bin t2 t1
+
+t1 = RR.apply [(return        , swap)]      exTree4
+t2 = RR.apply [(down          , swap)]      exTree4
+t3 = RR.apply [(down >=> right, swap)]      exTree4
+t4 = RR.apply [(down >=> right, swap), (return, swap)] exTree4 -- == id
+
+-- A tricky example
+ruleSwapC, ruleAddB :: Rule X
+ruleSwapC = rule $ \x y -> XC x y :~> XC y x
+ruleAddB  = rule $ \x   -> XA x   :~> XA (XB x)
+
+t6 = RR.apply [(down >=> down >=> down, ruleSwapC)] exX1
+t7 = RR.apply [(down >=> down,          ruleAddB)]  (fromJust t6)
+t8 = RR.apply [(return,                 ruleAddB)]  (fromJust t7)
+t9 = t8 == Just exX2 -- True
+
+--------------------------------------------------------------------------------
+-- Other ZipperState examples
+--------------------------------------------------------------------------------
+-- An example using a zipper with state
+t5 = navigate exTree4 $
+       do downMonad >> downMonad
+          saveMonad
+          upMonad >> rightMonad >> downMonad >> rightMonad
+          saveMonad
+          x1 <- loadMonad
+          updateMonad (const x1)
+          upMonad >> leftMonad >> downMonad
+          x2 <- loadMonad
+          updateMonad (const x2)
+
+--------------------------------------------------------------------------------
+-- A nicer interface for Expr, could be generated using Template Haskell
+--------------------------------------------------------------------------------
+data ExprEH
+  = VarEH String
+  | ConstEH Integer
+  | NegEH ExprEH
+  | AddEH ExprEH ExprEH
+  | RefEH Path
+  deriving Show
+
+class HasRef a where
+  type RefRep a
+  
+  toRef   :: Fix (WithRef a) -> RefRep a
+  fromRef :: RefRep a -> Fix (WithRef a)
+
+instance HasRef Expr where
+  type RefRep Expr = ExprEH
+  
+  toRef (In (Ref p))                           = RefEH p
+  toRef (In (InR (L (K s))))                   = VarEH s
+  toRef (In (InR (R (L (K i)))))               = ConstEH i
+  toRef (In (InR (R (R (L (I e))))))           = NegEH (toRef e)
+  toRef (In (InR (R (R (R (I e1 :*: I e2)))))) = AddEH (toRef e1) (toRef e2)
+  
+  fromRef (RefEH p)     = In (Ref p)
+  fromRef (VarEH s)      = In (InR (L (K s)))
+  fromRef (ConstEH i)    = In (InR (R (L (K i))))
+  fromRef (NegEH e)      = In (InR (R (R (L (I (fromRef e))))))
+  fromRef (AddEH e1 e2)  = In (InR (R (R (R (I (fromRef e1) :*: I (fromRef e2))))))
+
+
+-- Provide the interface
+type NiceTransformation a = [ (Path, RefRep a) ] 
+
+toNiceTransformation :: HasRef a => Ex.Transformation a -> NiceTransformation a
+toNiceTransformation = map (\(p,e) -> (p, toRef e))
+
+fromNiceTransformation :: HasRef a => NiceTransformation a -> Ex.Transformation a
+fromNiceTransformation = map (\(p,e) -> (p,fromRef e))
+
+explicitInsNice :: Maybe Expr
+explicitInsNice = Ex.apply (fromNiceTransformation addNeg) expr1
+  where addNeg :: NiceTransformation Expr
+        addNeg = [ ([1], NegEH (RefEH [1])) ]
+ transformations.cabal view
@@ -0,0 +1,53 @@+name:                transformations
+version:             0.1.0.0
+synopsis:            Generic representation of tree transformations
+description:
+  This library is based on ideas described in the paper:
+  .
+  *  Jeroen Bransen and Jose Pedro Magalhaes.
+     /Generic Representations of Tree Transformations/.
+     <http://dreixel.net/research/pdf/grtt_draft.pdf>
+
+license:             GPL-3
+license-file:        LICENSE
+author:              Jeroen Bransen and Jose Pedro Magalhaes
+maintainer:          generics@haskell.org
+-- copyright:           
+category:            Language
+build-type:          Simple
+cabal-version:       >=1.8
+
+
+extra-source-files:    examples/Datatypes.hs
+                       examples/Lang.lhs
+                       examples/Regular.hs
+                       examples/MultiRec.hs
+
+library
+  exposed-modules:
+                       -- Regular part
+                       Generics.Regular.Zipper,
+                       Generics.Regular.Functions.GOrd,
+                       Generics.Regular.Transformations.Explicit,
+                       Generics.Regular.Transformations.RewriteRules,
+                       Generics.Regular.Transformations.ZipperState,
+  
+                       -- MultiRec implementation
+                       Generics.MultiRec.Any,
+                       Generics.MultiRec.Ord,
+                       Generics.MultiRec.Transformations.ZipperState,
+                       Generics.MultiRec.Transformations.RewriteRules,
+                       Generics.MultiRec.Transformations.Explicit,
+
+                       -- Rewriting library for MultiRec
+                       Generics.MultiRec.HZip,
+                       Generics.MultiRec.LR,
+                       Generics.MultiRec.Rewriting,
+                       Generics.MultiRec.Rewriting.Machinery,
+                       Generics.MultiRec.Rewriting.Rules
+
+  -- other-modules:       
+  build-depends:       base >= 4 && < 5, mtl >= 2.1,
+                       regular >= 0.3, rewriting >= 0.2,
+                       multirec >= 0.7.3, zipper >= 0.4.2,
+                       parsec >= 3.1, containers >= 0.1