diff --git a/Changelog.md b/Changelog.md
new file mode 100644
--- /dev/null
+++ b/Changelog.md
@@ -0,0 +1,27 @@
+# 0.4.0.1
+
+Moved all files into move idiomatic folders.
+
+# 0.3.1.0
+
+Fixed build, by removing internal uses of outdated EitherT.
+
+# 0.3.0.1
+
+New Smart constructors and user defined functions
+
+# 0.2.0.1
+
+Fixed parsing of builtin regex and contains functions.
+
+# 0.2.0.0
+
+New benchmarks
+
+# 0.1.1.0
+
+Cleanup
+
+# 0.1.0.0
+
+First version
diff --git a/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,36 @@
+.PHONY: run test setup bench doc pkg
+
+build:
+	stack build --bench --no-run-benchmarks
+
+test: build
+	stack test
+
+singletest: build
+	stack test --ta '-p "Derive"'
+
+test-trace: build
+	stack test --trace
+
+bench:
+	stack bench
+
+run: build
+	stack exec katydid-exe
+
+setup:
+	stack setup
+
+ide-setup:
+	stack build intero
+
+doc:
+	stack haddock --haddock-arguments "--odir=./docs"
+
+lint:
+	# -XNoPatternSynonyms is a temporary workaround for https://github.com/ndmitchell/hlint/issues/216
+	hlint -XNoPatternSynonyms .
+
+pkg: doc
+	stack sdist
+	echo "Now upload the created file to: https://hackage.haskell.org/upload"
diff --git a/README.md b/README.md
deleted file mode 100644
--- a/README.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Katydid
-
-[![Build Status](https://travis-ci.org/katydid/katydid-haskell.svg?branch=master)](https://travis-ci.org/katydid/katydid-haskell)
-
-A Haskell implementation of Katydid.
-
-![Katydid Logo](https://cdn.rawgit.com/katydid/katydid.github.io/master/logo.png)
-
-This includes:
-
-  - [Relapse](https://katydid.github.io/katydid-haskell/Relapse.html): Validation Language 
-  - Parsers: [JSON](https://katydid.github.io/katydid-haskell/Json.html) and [XML](https://katydid.github.io/katydid-haskell/Xml.html)
-
-[Documentation for katydid](http://katydid.github.io/)
-
-[Documentation for katydid-haskell](https://katydid.github.io/katydid-haskell/)
-
-[Documentation for katydid-haskell/Relapse](https://katydid.github.io/katydid-haskell/Relapse.html)
-
-All JSON and XML tests from [the language agnostic test suite](https://github.com/katydid/testsuite) [passes].
-
-[Hackage](https://hackage.haskell.org/package/katydid-0.1.0.0)
-
-## Example
-
-Validating a single structure can be done using the validate function:
-```haskell
-validate :: Tree t => Grammar -> [t] -> Bool
-```
-
-, where a tree is a class in the [Parsers](https://katydid.github.io/katydid-haskell/Parsers.html) module:
-```haskell
-class Tree a where
-    getLabel :: a -> Label
-    getChildren :: a -> [a]
-```
-
-Here is an example that validates a single JSON tree:
-```haskell
-main = either 
-    (\err -> putStrLn $ "error:" ++ err) 
-    (\valid -> if valid 
-        then putStrLn "dragons exist" 
-        else putStrLn "dragons are fictional"
-    ) $
-    Relapse.validate <$> 
-        Relapse.parse ".DragonsExist == true" <*> 
-        Json.decodeJSON "{\"DragonsExist\": false}"
-```
-
-## Efficiency
-
-If you want to validate multiple trees using the same grammar then the filter function does some internal memoization, which makes a huge difference.
-
-```haskell
-filter :: Tree t => Grammar -> [[t]] -> [[t]]
-```
-
-## User Defined Functions
-
-If you want to create your own extra functions for operating on the leaves,
-then you can inject them into the parse function:
-
-```haskell
-main = either
-    (\err -> putStrLn $ "error:" ++ err)
-    (\valid -> if valid
-        then putStrLn "prime birthday !!!"
-        else putStrLn "JOMO"
-    ) $
-    Relapse.validate <$>
-        Relapse.parseWithUDFs userLib ".Survived->isPrime($int)" <*>
-        Json.decodeJSON "{\"Survived\": 104743}"
-```
-
-Defining your own user library to inject is easy.
-The `Expr` library provides many useful helper functions:
-
-```haskell
-import Data.Numbers.Primes (isPrime)
-import Expr
-
-userLib :: String -> [AnyExpr] -> Either String AnyExpr
-userLib "isPrime" args = mkIsPrime args
-userLib n _ = throwError $ "undefined function: " ++ n
-
-mkIsPrime :: [AnyExpr] -> Either String AnyExpr
-mkIsPrime args = do {
-    arg <- assertArgs1 "isPrime" args;
-    mkBoolExpr . isPrimeExpr <$> assertInt arg;
-}
-
-isPrimeExpr :: Integral a => Expr a -> Expr Bool
-isPrimeExpr numExpr = trimBool Expr {
-    desc = mkDesc "isPrime" [desc numExpr]
-    , eval = \fieldValue -> isPrime <$> eval numExpr fieldValue
-}
-```
-
-## Roadmap
-
-  - Protobuf parser
-  - Profile and Optimize (bring up to par with Go version)
-  - Typed DSL (Combinator)
diff --git a/Readme.md b/Readme.md
new file mode 100644
--- /dev/null
+++ b/Readme.md
@@ -0,0 +1,104 @@
+# Katydid
+
+[![Build Status](https://travis-ci.org/katydid/katydid-haskell.svg?branch=master)](https://travis-ci.org/katydid/katydid-haskell)
+
+A Haskell implementation of Katydid.
+
+![Katydid Logo](https://cdn.rawgit.com/katydid/katydid.github.io/master/logo.png)
+
+This includes:
+
+  - [Relapse](https://katydid.github.io/katydid-haskell/Relapse.html): Validation Language 
+  - Parsers: [JSON](https://katydid.github.io/katydid-haskell/Json.html) and [XML](https://katydid.github.io/katydid-haskell/Xml.html)
+
+[Documentation for katydid](http://katydid.github.io/)
+
+[Documentation for katydid-haskell](https://katydid.github.io/katydid-haskell/)
+
+[Documentation for katydid-haskell/Relapse](https://katydid.github.io/katydid-haskell/Relapse.html)
+
+All JSON and XML tests from [the language agnostic test suite](https://github.com/katydid/testsuite) [passes].
+
+[Hackage](https://hackage.haskell.org/package/katydid)
+
+## Example
+
+Validating a single structure can be done using the validate function:
+```haskell
+validate :: Tree t => Grammar -> [t] -> Bool
+```
+
+, where a tree is a class in the [Parsers](https://katydid.github.io/katydid-haskell/Parsers.html) module:
+```haskell
+class Tree a where
+    getLabel :: a -> Label
+    getChildren :: a -> [a]
+```
+
+Here is an example that validates a single JSON tree:
+```haskell
+main = either 
+    (\err -> putStrLn $ "error:" ++ err) 
+    (\valid -> if valid 
+        then putStrLn "dragons exist" 
+        else putStrLn "dragons are fictional"
+    ) $
+    Relapse.validate <$> 
+        Relapse.parse ".DragonsExist == true" <*> 
+        Json.decodeJSON "{\"DragonsExist\": false}"
+```
+
+## Efficiency
+
+If you want to validate multiple trees using the same grammar then the filter function does some internal memoization, which makes a huge difference.
+
+```haskell
+filter :: Tree t => Grammar -> [[t]] -> [[t]]
+```
+
+## User Defined Functions
+
+If you want to create your own extra functions for operating on the leaves,
+then you can inject them into the parse function:
+
+```haskell
+main = either
+    (\err -> putStrLn $ "error:" ++ err)
+    (\valid -> if valid
+        then putStrLn "prime birthday !!!"
+        else putStrLn "JOMO"
+    ) $
+    Relapse.validate <$>
+        Relapse.parseWithUDFs userLib ".Survived->isPrime($int)" <*>
+        Json.decodeJSON "{\"Survived\": 104743}"
+```
+
+Defining your own user library to inject is easy.
+The `Expr` library provides many useful helper functions:
+
+```haskell
+import Data.Numbers.Primes (isPrime)
+import Data.Katydid.Relapse.Expr
+
+userLib :: String -> [AnyExpr] -> Either String AnyExpr
+userLib "isPrime" args = mkIsPrime args
+userLib n _ = throwError $ "undefined function: " ++ n
+
+mkIsPrime :: [AnyExpr] -> Either String AnyExpr
+mkIsPrime args = do {
+    arg <- assertArgs1 "isPrime" args;
+    mkBoolExpr . isPrimeExpr <$> assertInt arg;
+}
+
+isPrimeExpr :: Integral a => Expr a -> Expr Bool
+isPrimeExpr numExpr = trimBool Expr {
+    desc = mkDesc "isPrime" [desc numExpr]
+    , eval = \fieldValue -> isPrime <$> eval numExpr fieldValue
+}
+```
+
+## Roadmap
+
+  - Protobuf parser
+  - Profile and Optimize (bring up to par with Go version)
+  - Typed DSL (Combinator)
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -1,7 +1,7 @@
 module Main where
 
-import qualified Relapse
-import qualified Json
+import qualified Data.Katydid.Relapse.Relapse as Relapse
+import qualified Data.Katydid.Parser.Json as Json
 
 main :: IO ()
 main = either 
diff --git a/bench/Suite.hs b/bench/Suite.hs
--- a/bench/Suite.hs
+++ b/bench/Suite.hs
@@ -15,12 +15,12 @@
 import GHC.Generics (Generic)
 import Data.Int (Int64)
 
-import qualified Ast
-import Json (JsonTree, decodeJSON)
-import Xml (decodeXML)
-import qualified Parser
+import Data.Katydid.Parser.Json (JsonTree, decodeJSON)
+import Data.Katydid.Parser.Xml (decodeXML)
 
-import qualified Relapse
+import qualified Data.Katydid.Relapse.Ast as Ast
+import qualified Data.Katydid.Relapse.Parser as Parser
+import qualified Data.Katydid.Relapse.Relapse as Relapse
 
 runBench :: BenchSuiteCase -> IO Int
 runBench (BenchSuiteCase _ g (XMLDatas inputs)) =
diff --git a/changelog.md b/changelog.md
deleted file mode 100644
--- a/changelog.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# 2.0.1
-
-Fixes parsing of builtin regex and contains functions.
-
-# 2.0.0
-
-Adds benchmarks
-
-# 1.1.0
-
-Cleanup
-
-# 1.0.0
-
-First version
diff --git a/katydid.cabal b/katydid.cabal
--- a/katydid.cabal
+++ b/katydid.cabal
@@ -1,127 +1,169 @@
-name:                katydid
-version:             0.3.1.0
-synopsis:            A haskell implementation of Katydid
-description:         
-  A haskell implementation of Katydid
-  .
-  This includes:
-  .
-      - Relapse, a validation Language
-      - Parsers for JSON, XML and an abstraction for trees
-  .
-  You should only need the following modules:
-  .
-      - The Relapse module is used for validation.
-      - The Json and XML modules are used to create Json and XML trees that can be validated.
-  .
-  If you want to implement your own parser then you can look at the Parsers module
-  .
+-- This file has been generated from package.yaml by hpack version 0.28.2.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 5afbe6708301b18023de469fa4847a36e4c9612c2c60efdbf4e30ad3145b4636
 
-homepage:            https://github.com/katydid/katydid-haskell
-license:             BSD3
-license-file:        LICENSE
-author:              Walter Schulze
-maintainer:          awalterschulze@gmail.com
-copyright:           Walter Schulze
-category:            Data
-build-type:          Simple
-extra-source-files:  README.md, changelog.md
-cabal-version:       >=1.10
+name:           katydid
+version:        0.4.0.1
+synopsis:       A haskell implementation of Katydid
+description:    Please see the README on GitHub at <https://github.com/katydid/katydid-haskell#readme>
+category:       Data
+homepage:       https://github.com/katydid/katydid-haskell#readme
+bug-reports:    https://github.com/katydid/katydid-haskell/issues
+author:         Walter Schulze
+maintainer:     awalterschulze@gmail.com
+copyright:      Walter Schulze
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.10
+extra-source-files:
+    Changelog.md
+    LICENSE
+    Makefile
+    package.yaml
+    Readme.md
+    stack.yaml
 
+source-repository head
+  type: git
+  location: https://github.com/katydid/katydid-haskell
+
 library
-  hs-source-dirs:      src
-  exposed-modules:   Ast
-                     , Derive
-                     , MemDerive
-                     , Zip
-                     , IfExprs
-                     , Expr
-                     , Exprs.Compare
-                     , Exprs.Contains
-                     , Exprs.Elem
-                     , Exprs.Length
-                     , Exprs.Logic
-                     , Exprs.Strings
-                     , Exprs.Type
-                     , Exprs.Var
-                     , Exprs
-                     , Simplify
-                     , Json
-                     , Xml
-                     , Parsers
-                     , VpaDerive
-                     , Parser
-                     , Relapse
-                     , Smart
-  build-depends:       base >= 4.7 && < 5
-                     , containers
-                     , json
-                     , hxt
-                     , regex-tdfa
-                     , mtl
-                     , parsec
-                     , deepseq
-                     , text
-                     , bytestring
-                     , either
-                     , extra
-                     , ilist
-                     , transformers
-  default-language:    Haskell2010
+  exposed-modules:
+      Data.Katydid.Parser.Json
+      Data.Katydid.Parser.Parser
+      Data.Katydid.Parser.Xml
+      Data.Katydid.Relapse.Ast
+      Data.Katydid.Relapse.Derive
+      Data.Katydid.Relapse.Expr
+      Data.Katydid.Relapse.Exprs
+      Data.Katydid.Relapse.Exprs.Compare
+      Data.Katydid.Relapse.Exprs.Contains
+      Data.Katydid.Relapse.Exprs.Elem
+      Data.Katydid.Relapse.Exprs.Length
+      Data.Katydid.Relapse.Exprs.Logic
+      Data.Katydid.Relapse.Exprs.Strings
+      Data.Katydid.Relapse.Exprs.Type
+      Data.Katydid.Relapse.Exprs.Var
+      Data.Katydid.Relapse.IfExprs
+      Data.Katydid.Relapse.MemDerive
+      Data.Katydid.Relapse.Parser
+      Data.Katydid.Relapse.Relapse
+      Data.Katydid.Relapse.Simplify
+      Data.Katydid.Relapse.Smart
+      Data.Katydid.Relapse.VpaDerive
+      Data.Katydid.Relapse.Zip
+  other-modules:
+      Paths_katydid
+  hs-source-dirs:
+      src
+  build-depends:
+      base >=4.7 && <5
+    , bytestring
+    , containers
+    , deepseq
+    , either
+    , extra
+    , hxt
+    , ilist
+    , json
+    , mtl
+    , parsec
+    , regex-tdfa
+    , text
+    , transformers
+  default-language: Haskell2010
 
 executable katydid-exe
-  hs-source-dirs:      app
-  main-is:             Main.hs
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
-  build-depends:       base
-                     , katydid
-                     , mtl
-  default-language:    Haskell2010
+  main-is: Main.hs
+  other-modules:
+      Paths_katydid
+  hs-source-dirs:
+      app
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      base >=4.7 && <5
+    , bytestring
+    , containers
+    , deepseq
+    , either
+    , extra
+    , hxt
+    , ilist
+    , json
+    , katydid
+    , mtl
+    , parsec
+    , regex-tdfa
+    , text
+    , transformers
+  default-language: Haskell2010
 
 test-suite katydid-test
-  type:                exitcode-stdio-1.0
-  hs-source-dirs:      test
-  main-is:             Spec.hs
-  build-depends:       base
-                     , katydid
-                     , directory
-                     , filepath
-                     , containers
-                     , json
-                     , hxt
-                     , HUnit
-                     , parsec
-                     , mtl
-                     , tasty-hunit
-                     , tasty
-                     , text
-                     , primes
-                     , ilist
-  other-modules:     UserDefinedFuncs
-                     , ParserSpec
-                     , RelapseSpec
-                     , Suite
-                     , DeriveSpec
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
-  default-language:    Haskell2010
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      DeriveSpec
+      ParserSpec
+      RelapseSpec
+      Suite
+      UserDefinedFuncs
+      Paths_katydid
+  hs-source-dirs:
+      test
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      HUnit
+    , base >=4.7 && <5
+    , bytestring
+    , containers
+    , deepseq
+    , directory
+    , either
+    , extra
+    , filepath
+    , hxt
+    , ilist
+    , json
+    , katydid
+    , mtl
+    , parsec
+    , primes
+    , regex-tdfa
+    , tasty
+    , tasty-hunit
+    , text
+    , transformers
+  default-language: Haskell2010
 
-benchmark criterion-benchmarks
-  type:             exitcode-stdio-1.0
-  hs-source-dirs:   bench
-  main-is:          Benchmarks.hs
-  build-depends:    base
-                  , katydid
-                  , criterion >= 1.2.2
-                  , directory
-                  , filepath
-                  , mtl
-                  , hxt
-                  , deepseq
-                  , text
-  other-modules:    Suite
-  ghc-options:      -Wall
+benchmark katydid-benchmark
+  type: exitcode-stdio-1.0
+  main-is: Benchmarks.hs
+  other-modules:
+      Suite
+      Paths_katydid
+  hs-source-dirs:
+      bench
+  ghc-options: -Wall
+  build-depends:
+      base >=4.7 && <5
+    , bytestring
+    , containers
+    , criterion >=1.2.2
+    , deepseq
+    , directory
+    , either
+    , extra
+    , filepath
+    , hxt
+    , ilist
+    , json
+    , katydid
+    , mtl
+    , parsec
+    , regex-tdfa
+    , text
+    , transformers
   default-language: Haskell2010
-  
-source-repository head
-  type:     git
-  location: https://github.com/katydid/katydid-haskell
diff --git a/package.yaml b/package.yaml
new file mode 100644
--- /dev/null
+++ b/package.yaml
@@ -0,0 +1,83 @@
+name:                katydid
+version:             0.4.0.1
+github:              "katydid/katydid-haskell"
+license:             BSD3
+author:              "Walter Schulze"
+maintainer:          "awalterschulze@gmail.com"
+copyright:           "Walter Schulze"
+
+extra-source-files:
+- Readme.md
+- LICENSE
+- Makefile
+- Changelog.md
+- package.yaml
+- stack.yaml
+
+# Metadata used when publishing your package
+synopsis:            A haskell implementation of Katydid
+category:            Data
+
+# To avoid duplicated efforts in documentation and dealing with the
+# complications of embedding Haddock markup inside cabal files, it is
+# common to point users to the README.md file.
+description:         Please see the README on GitHub at <https://github.com/katydid/katydid-haskell#readme>
+
+dependencies:
+- base >= 4.7 && < 5
+- containers
+- json
+- hxt
+- regex-tdfa
+- mtl
+- parsec
+- deepseq
+- text
+- bytestring
+- either
+- extra
+- ilist
+- transformers
+
+library:
+  source-dirs: src
+
+executables:
+  katydid-exe:
+    main:                Main.hs
+    source-dirs:         app
+    ghc-options:
+    - -threaded
+    - -rtsopts
+    - -with-rtsopts=-N
+    dependencies:
+    - katydid
+
+tests:
+  katydid-test:
+    main:                Spec.hs
+    source-dirs:         test
+    ghc-options:
+    - -threaded
+    - -rtsopts
+    - -with-rtsopts=-N
+    dependencies:
+    - katydid
+    - directory
+    - filepath
+    - HUnit
+    - tasty-hunit
+    - tasty
+    - primes
+
+benchmarks:
+  katydid-benchmark:
+    main: Benchmarks.hs
+    source-dirs: bench
+    ghc-options:
+    - -Wall
+    dependencies:
+    - katydid
+    - criterion >= 1.2.2
+    - directory
+    - filepath
diff --git a/src/Ast.hs b/src/Ast.hs
deleted file mode 100644
--- a/src/Ast.hs
+++ /dev/null
@@ -1,117 +0,0 @@
--- |
--- This module describes the Relapse's abstract syntax tree.
---
--- It also contains some simple functions for the map of references that a Relapse grammar consists of.
---
--- Finally it also contains some very simple pattern functions.
-module Ast (
-    Pattern(..)
-    , Grammar, emptyRef, union, newRef, reverseLookupRef, lookupRef, hasRecursion, listRefs
-    , nullable
-) where
-
-import qualified Data.Map.Strict as M
-import qualified Data.Set as S
-import Control.Monad.Extra ((||^), (&&^))
-
-import Expr
-
--- |
--- Pattern recursively describes a Relapse Pattern.
-data Pattern
-    = Empty
-    | ZAny
-    | Node (Expr Bool) Pattern
-    | Or Pattern Pattern
-    | And Pattern Pattern
-    | Not Pattern
-    | Concat Pattern Pattern
-    | Interleave Pattern Pattern
-    | ZeroOrMore Pattern
-    | Optional Pattern
-    | Contains Pattern
-    | Reference String
-    deriving (Eq, Ord, Show)
-
--- |
--- The nullable function returns whether a pattern is nullable.
--- This means that the pattern matches the empty string.
-nullable :: Grammar -> Pattern -> Either String Bool
-nullable _ Empty = Right True
-nullable _ ZAny = Right True
-nullable _ Node{} = Right False
-nullable g (Or l r) = nullable g l ||^ nullable g r
-nullable g (And l r) = nullable g l &&^ nullable g r
-nullable g (Not p) = not <$> nullable g p
-nullable g (Concat l r) = nullable g l &&^ nullable g r
-nullable g (Interleave l r) = nullable g l &&^ nullable g r
-nullable _ (ZeroOrMore _) = Right True
-nullable _ (Optional _) = Right True
-nullable g (Contains p) = nullable g p
-nullable g (Reference refName) = lookupRef g refName >>= nullable g
-
--- |
--- Refs is a map from reference name to pattern and describes a relapse grammar.
-newtype Grammar = Grammar (M.Map String Pattern)
-    deriving (Show, Eq)
-
--- |
--- lookupRef looks up a pattern in the reference map, given a reference name.
-lookupRef :: Grammar -> String -> Either String Pattern
-lookupRef (Grammar m) refName = case M.lookup refName m of
-    Nothing -> Left $ "missing reference: " ++ refName
-    (Just p) -> Right p
-
--- |
--- listRefs returns the list of reference names.
-listRefs :: Grammar -> [String]
-listRefs (Grammar m) = M.keys m
-
--- |
--- reverseLookupRef returns the reference name for a given pattern.
-reverseLookupRef :: Pattern -> Grammar -> Maybe String
-reverseLookupRef p (Grammar m) = case M.keys $ M.filter (== p) m of
-    []      -> Nothing
-    (k:_)  -> Just k
-
--- |
--- newRef returns a new reference map given a single pattern and its reference name.
-newRef :: String -> Pattern -> Grammar
-newRef key value = Grammar $ M.singleton key value
-
--- |
--- emptyRef returns an empty reference map.
-emptyRef :: Grammar
-emptyRef = Grammar M.empty
-
--- |
--- union returns the union of two reference maps.
-union :: Grammar -> Grammar -> Grammar
-union (Grammar m1) (Grammar m2) = Grammar $ M.union m1 m2 
-
--- |
--- hasRecursion returns whether an relapse grammar has any recursion, starting from the "main" reference.
-hasRecursion :: Grammar -> Either String Bool
-hasRecursion g = do {
-    mainPat <- lookupRef g "main";
-    hasRec g (S.singleton "main") mainPat 
-}
-
-hasRec :: Grammar -> S.Set String -> Pattern -> Either String Bool
-hasRec _ _ Empty = Right False
-hasRec _ _ ZAny = Right False
-hasRec _ _ Node{} = Right False
-hasRec g set (Or l r) = hasRec g set l ||^ hasRec g set r
-hasRec g set (And l r) = hasRec g set l ||^ hasRec g set r
-hasRec g set (Not p) = hasRec g set p
-hasRec g set (Concat l r) = hasRec g set l ||^ (nullable g l &&^ hasRec g set r)
-hasRec g set (Interleave l r) = hasRec g set l ||^ hasRec g set r
-hasRec g set (ZeroOrMore p) = hasRec g set p
-hasRec g set (Optional p) = hasRec g set p
-hasRec g set (Contains p) = hasRec g set p
-hasRec g set (Reference refName) = if S.member refName set
-    then Right True
-    else do {
-        pat <- lookupRef g refName;
-        hasRec g (S.insert refName set) pat;
-    }
diff --git a/src/Data/Katydid/Parser/Json.hs b/src/Data/Katydid/Parser/Json.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Parser/Json.hs
@@ -0,0 +1,50 @@
+{-# LANGUAGE FlexibleInstances #-}
+
+-- |
+-- This module contains the Json Parser.
+
+module Data.Katydid.Parser.Json (
+    decodeJSON, JsonTree
+) where
+
+import Text.JSON (decode, Result(..), JSValue(..), fromJSString, fromJSObject)
+import Data.Ratio (denominator)
+import Data.Text (pack)
+
+import qualified Data.Tree as DataTree
+import Data.Katydid.Parser.Parser
+
+instance Tree JsonTree where
+    getLabel (DataTree.Node l _) = l
+    getChildren (DataTree.Node _ cs) = cs
+
+-- |
+-- JsonTree is a tree that can be validated by Relapse.
+type JsonTree = DataTree.Tree Label
+
+-- |
+-- decodeJSON returns a JsonTree, given an input string.
+decodeJSON :: String -> Either String [JsonTree]
+decodeJSON s = case decode s of
+    (Error e) -> Left e
+    (Ok v) -> Right (uValue v)
+
+uValue :: JSValue -> [JsonTree]
+uValue JSNull = []
+uValue (JSBool b) = [DataTree.Node (Bool b) []]
+uValue (JSRational _ r) = if denominator r /= 1 
+    then [DataTree.Node (Double (fromRational r :: Double)) []]
+    else [DataTree.Node (Int $ truncate r) []]
+uValue (JSString s) = [DataTree.Node (String $ pack $ fromJSString s) []]
+uValue (JSArray vs) = uArray 0 vs
+uValue (JSObject o) = uObject $ fromJSObject o
+
+uArray :: Int -> [JSValue] -> [JsonTree]
+uArray _ [] = []
+uArray index (v:vs) = DataTree.Node (Int index) (uValue v):uArray (index+1) vs
+
+uObject :: [(String, JSValue)] -> [JsonTree]
+uObject = map uKeyValue
+
+uKeyValue :: (String, JSValue) -> JsonTree
+uKeyValue (name, value) = DataTree.Node (String $ pack name) (uValue value)
diff --git a/src/Data/Katydid/Parser/Parser.hs b/src/Data/Katydid/Parser/Parser.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Parser/Parser.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
+
+-- |
+-- This module describes the abstract tree that can be validated by Relapse.
+--
+-- The JSON and XML parsers both are both versions of this type class.
+
+module Data.Katydid.Parser.Parser (
+    Tree(..), Label(..)
+) where
+
+import Control.DeepSeq (NFData)
+import GHC.Generics (Generic)
+import Data.Text (Text)
+import Data.ByteString (ByteString)
+
+-- |
+-- Label is a tagged union of all possible value types that can returned by a katydid parser: 
+-- String, Int, Uint, Double, Bool and Bytes.
+data Label
+    = String Text
+    | Int Int
+    | Uint Word
+    | Double Double
+    | Bool Bool
+    | Bytes ByteString
+    deriving (Show, Eq, Ord, Generic, NFData)
+
+-- |
+-- Tree is the type class that should be implemented by a katydid parser.
+-- This is implemented by the Json and XML parser.
+class Tree a where
+    getLabel :: a -> Label
+    getChildren :: a -> [a]
diff --git a/src/Data/Katydid/Parser/Xml.hs b/src/Data/Katydid/Parser/Xml.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Parser/Xml.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE FlexibleInstances #-}
+
+-- |
+-- This module contains the XML Parser.
+
+module Data.Katydid.Parser.Xml (
+    decodeXML
+) where
+
+import Text.Read (readMaybe)
+import Text.XML.HXT.DOM.TypeDefs (XmlTree, XNode(..), blobToString, localPart)
+import Text.XML.HXT.Parser.XmlParsec (xread)
+import Data.Tree.NTree.TypeDefs (NTree(..))
+import qualified Data.Text as Text
+
+import Data.Katydid.Parser.Parser
+
+instance Tree XmlTree where
+    getLabel (NTree n _ ) = either (String . Text.pack . ("XML Parse Error:" ++)) id (xmlLabel n)
+    getChildren (NTree _ cs) = cs
+
+-- |
+-- decodeXML returns a XmlTree, given an input string.
+decodeXML :: String -> [XmlTree]
+decodeXML = xread
+
+xmlLabel :: XNode -> Either String Label
+xmlLabel (XText s) = return $ parseLabel s
+xmlLabel (XBlob b) = return $ parseLabel $ blobToString b
+xmlLabel x@(XCharRef _) = fail $ "XCharRef not supported" ++ show x
+xmlLabel x@(XEntityRef _) = fail $ "XEntityRef not supported" ++ show x
+xmlLabel x@(XCmt _) = fail $ "XCmt not supported" ++ show x
+xmlLabel (XCdata s) = return $ parseLabel s
+xmlLabel x@XPi{} = fail $ "XPi not supported" ++ show x
+xmlLabel (XTag qname attrs) = return $ parseLabel (localPart qname) -- TODO attrs should be part of the children returned by getChildren
+xmlLabel x@XDTD{} = fail $ "XDTD not supported" ++ show x
+xmlLabel (XAttr qname) = return $ parseLabel (localPart qname)
+xmlLabel x@XError{} = fail $ "XError not supported" ++ show x
+
+-- TODO what about other leaf types
+parseLabel :: String -> Label
+parseLabel s = maybe (String (Text.pack s)) Int (readMaybe s :: Maybe Int)
diff --git a/src/Data/Katydid/Relapse/Ast.hs b/src/Data/Katydid/Relapse/Ast.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Ast.hs
@@ -0,0 +1,117 @@
+-- |
+-- This module describes the Relapse's abstract syntax tree.
+--
+-- It also contains some simple functions for the map of references that a Relapse grammar consists of.
+--
+-- Finally it also contains some very simple pattern functions.
+module Data.Katydid.Relapse.Ast (
+    Pattern(..)
+    , Grammar, emptyRef, union, newRef, reverseLookupRef, lookupRef, hasRecursion, listRefs
+    , nullable
+) where
+
+import qualified Data.Map.Strict as M
+import qualified Data.Set as S
+import Control.Monad.Extra ((||^), (&&^))
+
+import Data.Katydid.Relapse.Expr
+
+-- |
+-- Pattern recursively describes a Relapse Pattern.
+data Pattern
+    = Empty
+    | ZAny
+    | Node (Expr Bool) Pattern
+    | Or Pattern Pattern
+    | And Pattern Pattern
+    | Not Pattern
+    | Concat Pattern Pattern
+    | Interleave Pattern Pattern
+    | ZeroOrMore Pattern
+    | Optional Pattern
+    | Contains Pattern
+    | Reference String
+    deriving (Eq, Ord, Show)
+
+-- |
+-- The nullable function returns whether a pattern is nullable.
+-- This means that the pattern matches the empty string.
+nullable :: Grammar -> Pattern -> Either String Bool
+nullable _ Empty = Right True
+nullable _ ZAny = Right True
+nullable _ Node{} = Right False
+nullable g (Or l r) = nullable g l ||^ nullable g r
+nullable g (And l r) = nullable g l &&^ nullable g r
+nullable g (Not p) = not <$> nullable g p
+nullable g (Concat l r) = nullable g l &&^ nullable g r
+nullable g (Interleave l r) = nullable g l &&^ nullable g r
+nullable _ (ZeroOrMore _) = Right True
+nullable _ (Optional _) = Right True
+nullable g (Contains p) = nullable g p
+nullable g (Reference refName) = lookupRef g refName >>= nullable g
+
+-- |
+-- Refs is a map from reference name to pattern and describes a relapse grammar.
+newtype Grammar = Grammar (M.Map String Pattern)
+    deriving (Show, Eq)
+
+-- |
+-- lookupRef looks up a pattern in the reference map, given a reference name.
+lookupRef :: Grammar -> String -> Either String Pattern
+lookupRef (Grammar m) refName = case M.lookup refName m of
+    Nothing -> Left $ "missing reference: " ++ refName
+    (Just p) -> Right p
+
+-- |
+-- listRefs returns the list of reference names.
+listRefs :: Grammar -> [String]
+listRefs (Grammar m) = M.keys m
+
+-- |
+-- reverseLookupRef returns the reference name for a given pattern.
+reverseLookupRef :: Pattern -> Grammar -> Maybe String
+reverseLookupRef p (Grammar m) = case M.keys $ M.filter (== p) m of
+    []      -> Nothing
+    (k:_)  -> Just k
+
+-- |
+-- newRef returns a new reference map given a single pattern and its reference name.
+newRef :: String -> Pattern -> Grammar
+newRef key value = Grammar $ M.singleton key value
+
+-- |
+-- emptyRef returns an empty reference map.
+emptyRef :: Grammar
+emptyRef = Grammar M.empty
+
+-- |
+-- union returns the union of two reference maps.
+union :: Grammar -> Grammar -> Grammar
+union (Grammar m1) (Grammar m2) = Grammar $ M.union m1 m2 
+
+-- |
+-- hasRecursion returns whether an relapse grammar has any recursion, starting from the "main" reference.
+hasRecursion :: Grammar -> Either String Bool
+hasRecursion g = do {
+    mainPat <- lookupRef g "main";
+    hasRec g (S.singleton "main") mainPat 
+}
+
+hasRec :: Grammar -> S.Set String -> Pattern -> Either String Bool
+hasRec _ _ Empty = Right False
+hasRec _ _ ZAny = Right False
+hasRec _ _ Node{} = Right False
+hasRec g set (Or l r) = hasRec g set l ||^ hasRec g set r
+hasRec g set (And l r) = hasRec g set l ||^ hasRec g set r
+hasRec g set (Not p) = hasRec g set p
+hasRec g set (Concat l r) = hasRec g set l ||^ (nullable g l &&^ hasRec g set r)
+hasRec g set (Interleave l r) = hasRec g set l ||^ hasRec g set r
+hasRec g set (ZeroOrMore p) = hasRec g set p
+hasRec g set (Optional p) = hasRec g set p
+hasRec g set (Contains p) = hasRec g set p
+hasRec g set (Reference refName) = if S.member refName set
+    then Right True
+    else do {
+        pat <- lookupRef g refName;
+        hasRec g (S.insert refName set) pat;
+    }
diff --git a/src/Data/Katydid/Relapse/Derive.hs b/src/Data/Katydid/Relapse/Derive.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Derive.hs
@@ -0,0 +1,165 @@
+-- |
+-- This module is a simple implementation of the internal derivative algorithm.
+--
+-- It is intended to be used for explanation purposes.
+--
+-- This means that it gives up speed for readability.
+--
+-- Thus it has no type of memoization.
+
+module Data.Katydid.Relapse.Derive (
+    derive, calls, returns, zipderive
+    -- * Internal functions
+    -- | These functions are exposed for testing purposes.
+    , removeOneForEach
+) where
+
+import Data.Foldable (foldlM)
+import Data.List.Index (imap)
+
+import Data.Katydid.Parser.Parser
+
+import Data.Katydid.Relapse.Smart
+import Data.Katydid.Relapse.Simplify
+import Data.Katydid.Relapse.Zip
+import Data.Katydid.Relapse.IfExprs
+
+-- | 
+-- calls returns a compiled if expression tree.
+-- Each if expression returns a child pattern, given the input value.
+-- In other words calls signature is actually:
+--
+-- @
+--   Refs -> [Pattern] -> Value -> [Pattern]
+-- @
+--
+-- , where the resulting list of patterns are the child patterns,
+-- that need to be derived given the trees child values.
+calls :: Grammar -> [Pattern] -> IfExprs
+calls g ps = compileIfExprs $ concatMap (\p -> deriveCall g p []) ps
+
+deriveCall :: Grammar -> Pattern -> [IfExpr] -> [IfExpr]
+deriveCall _ Empty res = res
+deriveCall _ ZAny res = res
+deriveCall _ Node{expr=v,pat=p} res = newIfExpr v p emptySet : res
+deriveCall g Concat{left=l,right=r} res
+    | nullable l = deriveCall g l (deriveCall g r res)
+    | otherwise = deriveCall g l res
+deriveCall g Or{pats=ps} res = foldr (deriveCall g) res ps
+deriveCall g And{pats=ps} res = foldr (deriveCall g) res ps
+deriveCall g Interleave{pats=ps} res = foldr (deriveCall g) res ps
+deriveCall g ZeroOrMore{pat=p} res = deriveCall g p res
+deriveCall g Reference{refName=name} res = deriveCall g (lookupRef g name) res
+deriveCall g Not{pat=p} res = deriveCall g p res
+deriveCall g Contains{pat=p} res = deriveCall g p res
+deriveCall g Optional{pat=p} res = deriveCall g p res
+
+-- |
+-- returns takes a list of patterns and list of bools.
+-- The list of bools represent the nullability of the derived child patterns.
+-- Each bool will then replace each Node pattern with either an Empty or EmptySet.
+-- The lists do not to be the same length, because each Pattern can contain an arbitrary number of Node Patterns.
+returns :: Grammar -> ([Pattern], [Bool]) -> [Pattern]
+returns _ ([], []) = []
+returns g (p:tailps, ns) =
+    let (dp, tailns) = deriveReturn g p ns
+    in  dp:returns g (tailps, tailns)
+
+mapReturn :: Grammar -> [Pattern] -> [Bool] -> ([Pattern], [Bool])
+mapReturn g ps ns = foldl (\(dps, tailns) p ->
+        let (dp, tailoftail) = deriveReturn g p tailns
+        in (dp:dps, tailoftail)
+    ) ([], ns) ps
+
+deriveReturn :: Grammar -> Pattern -> [Bool] -> (Pattern, [Bool])
+deriveReturn _ Empty ns = (emptySet, ns)
+deriveReturn _ ZAny ns = (zanyPat, ns)
+deriveReturn _ Node{} ns
+    | head ns = (emptyPat, tail ns)
+    | otherwise = (emptySet, tail ns)
+deriveReturn g Concat{left=l,right=r} ns
+    | nullable l =
+        let (dl, ltail) = deriveReturn g l ns
+            (dr, rtail) = deriveReturn g r ltail
+        in  (orPat (concatPat dl r) dr, rtail)
+    | otherwise =
+        let (dl, ltail) = deriveReturn g l ns
+        in  (concatPat dl r, ltail)
+deriveReturn g Or{pats=ps} ns =
+    let (dps, tailns) = mapReturn g ps ns
+    in (foldl1 orPat dps, tailns)
+deriveReturn g And{pats=ps} ns =
+    let (dps, tailns) = mapReturn g ps ns
+    in (foldl1 andPat dps, tailns)
+deriveReturn g Interleave{pats=ps} ns =
+    let (dps, tailns) = mapReturn g ps ns
+        pps = reverse $ removeOneForEach ps
+        ips = zipWith (:) dps pps
+        ors = map (foldl1 interleavePat) ips
+    in (foldl1 orPat ors, tailns)
+deriveReturn g z@ZeroOrMore{pat=p} ns =
+    let (dp, tailns) = deriveReturn g p ns
+    in  (concatPat dp z, tailns)
+deriveReturn g Reference{refName=name} ns = deriveReturn g (lookupRef g name) ns
+deriveReturn g Not{pat=p} ns =
+    let (dp, tailns) = deriveReturn g p ns
+    in  (notPat dp, tailns)
+deriveReturn g c@Contains{pat=p} ns =
+    let (dp, tailns) = deriveReturn g p ns
+    in  (orPat c (containsPat dp), tailns)
+deriveReturn g Optional{pat=p} ns = deriveReturn g p ns
+
+-- | For internal testing.
+-- removeOneForEach creates N copies of the list removing the n'th element from each.
+removeOneForEach :: [a] -> [[a]]
+removeOneForEach xs = imap (\index list ->
+        let (start,end) = splitAt index list
+        in start ++ tail end
+    ) (replicate (length xs) xs)
+
+-- |
+-- derive is the classic derivative implementation for trees.
+derive :: Tree t => Grammar -> [t] -> Either String Pattern
+derive g ts = do {
+    ps <- foldlM (deriv g) [lookupMain g] ts;
+    if length ps == 1 
+        then return $ head ps
+        else Left $ "Number of patterns is not one, but " ++ show ps
+}
+
+deriv :: Tree t => Grammar -> [Pattern] -> t -> Either String [Pattern]
+deriv g ps tree =
+    if all unescapable ps then return ps else
+    let ifs = calls g ps
+        d = deriv g
+        nulls = map nullable
+    in do {
+        childps <- evalIfExprs ifs (getLabel tree);
+        childres <- foldlM d childps (getChildren tree);
+        return $ returns g (ps, nulls childres);
+    }
+
+-- |
+-- zipderive is a slighty optimized version of derivs.
+-- It zips its intermediate pattern lists to reduce the state space.
+zipderive :: Tree t => Grammar -> [t] -> Either String Pattern
+zipderive g ts = do {
+    ps <- foldlM (zipderiv g) [lookupMain g] ts;
+    if length ps == 1 
+        then return $ head ps
+        else Left $ "Number of patterns is not one, but " ++ show ps
+}
+
+zipderiv :: Tree t => Grammar -> [Pattern] -> t -> Either String [Pattern]
+zipderiv g ps tree =
+    if all unescapable ps then return ps else
+    let ifs = calls g ps
+        d = zipderiv g
+        nulls = map nullable
+    in do {
+        childps <- evalIfExprs ifs (getLabel tree);
+        (zchildps, zipper) <- return $ zippy childps;
+        childres <- foldlM d zchildps (getChildren tree);
+        let unzipns = unzipby zipper (nulls childres)
+        in return $ returns g (ps, unzipns)
+    }
diff --git a/src/Data/Katydid/Relapse/Expr.hs b/src/Data/Katydid/Relapse/Expr.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Expr.hs
@@ -0,0 +1,509 @@
+-- |
+-- This module contains all the functions you need to implement a Relapse expression.
+
+module Data.Katydid.Relapse.Expr (
+    Desc(..), mkDesc
+    , AnyExpr(..), AnyFunc(..)
+    , Expr(..), Func, params, name, hasVar
+    , hashWithName, hashList, hashString
+    , evalConst, isConst
+    , assertArgs1, assertArgs2
+    , mkBoolExpr, mkIntExpr, mkStringExpr, mkDoubleExpr, mkBytesExpr, mkUintExpr
+    , assertBool, assertInt, assertString, assertDouble, assertBytes, assertUint
+    , boolExpr, intExpr, stringExpr, doubleExpr, bytesExpr, uintExpr
+    , trimBool, trimInt, trimString, trimDouble, trimBytes, trimUint
+    , mkBoolsExpr, mkIntsExpr, mkStringsExpr, mkDoublesExpr, mkListOfBytesExpr, mkUintsExpr
+    , assertBools, assertInts, assertStrings, assertDoubles, assertListOfBytes, assertUints
+    , boolsExpr, intsExpr, stringsExpr, doublesExpr, listOfBytesExpr, uintsExpr
+) where
+
+import Data.Char (ord)
+import Data.List (intercalate)
+import Data.Text (Text, unpack, pack)
+import Data.ByteString (ByteString)
+
+import qualified Data.Katydid.Parser.Parser as Parser
+
+-- |
+-- assertArgs1 asserts that the list of arguments is only one argument and 
+-- returns the argument or an error message 
+-- containing the function name that was passed in as an argument to assertArgs1.
+assertArgs1 :: String -> [AnyExpr] -> Either String AnyExpr
+assertArgs1 _ [e1] = Right e1
+assertArgs1 exprName es = Left $ exprName ++ ": expected one argument, but got " ++ show (length es) ++ ": " ++ show es
+
+-- |
+-- assertArgs2 asserts that the list of arguments is only two arguments and 
+-- returns the two arguments or an error message 
+-- containing the function name that was passed in as an argument to assertArgs2.
+assertArgs2 :: String -> [AnyExpr] -> Either String (AnyExpr, AnyExpr)
+assertArgs2 _ [e1, e2] = Right (e1, e2)
+assertArgs2 exprName es = Left $ exprName ++ ": expected two arguments, but got " ++ show (length es) ++ ": " ++ show es
+
+-- |
+-- Desc is the description of a function, 
+-- especially built to make comparisons of user defined expressions possible.
+data Desc = Desc {
+    _name :: String
+    , _toStr :: String
+    , _hash :: Int
+    , _params :: [Desc]
+    , _hasVar :: Bool
+}
+
+-- |
+-- mkDesc makes a description from a function name and a list of the argument's descriptions.
+mkDesc :: String -> [Desc] -> Desc
+mkDesc n ps = Desc {
+    _name = n
+    , _toStr = n ++ "(" ++ intercalate "," (map show ps) ++ ")"
+    , _hash = hashWithName n ps
+    , _params = ps
+    , _hasVar = any _hasVar ps
+}
+
+instance Show Desc where
+    show = _toStr
+
+instance Ord Desc where
+    compare = cmp
+
+instance Eq Desc where
+    (==) a b = cmp a b == EQ
+
+-- |
+-- AnyExpr is used by the Relapse parser to represent an Expression that can return any type of value, 
+-- where any is a predefined list of possible types represented by AnyFunc.
+data AnyExpr = AnyExpr {
+    _desc :: Desc
+    , _eval :: AnyFunc
+}
+
+-- |
+-- Func represents the evaluation function part of a user defined expression.
+-- This function takes a label from a tree parser and returns a value or an error string.
+type Func a = (Parser.Label -> Either String a)
+
+instance Show AnyExpr where
+    show a = show (_desc a)
+
+instance Eq AnyExpr where
+    (==) a b = _desc a == _desc b
+
+instance Ord AnyExpr where
+    compare a b = cmp (_desc a) (_desc b)
+
+-- |
+-- AnyFunc is used by the Relapse parser and represents the list all supported types of functions.
+data AnyFunc = BoolFunc (Func Bool)
+    | IntFunc (Func Int)
+    | StringFunc (Func Text)
+    | DoubleFunc (Func Double)
+    | UintFunc (Func Word)
+    | BytesFunc (Func ByteString)
+    | BoolsFunc (Func [Bool])
+    | IntsFunc (Func [Int])
+    | StringsFunc (Func [Text])
+    | DoublesFunc (Func [Double])
+    | UintsFunc (Func [Word])
+    | ListOfBytesFunc (Func [ByteString])
+
+-- |
+-- Expr represents a user defined expression, 
+-- which consists of a description for comparisons and an evaluation function.
+data Expr a = Expr {
+    desc :: Desc
+    , eval :: Func a
+}
+
+instance Show (Expr a) where
+    show e = show (desc e)
+
+instance Eq (Expr a) where
+    (==) x y = desc x == desc y
+
+instance Ord (Expr a) where
+    compare x y = cmp (desc x) (desc y)
+
+-- |
+-- params returns the descriptions of the parameters of the user defined expression.
+params :: Expr a -> [Desc]
+params = _params . desc
+
+-- |
+-- name returns the name of the user defined expression.
+name :: Expr a -> String
+name = _name . desc
+
+-- |
+-- hasVar returns whether the expression or any of its children contains a variable expression.
+hasVar :: Expr a -> Bool
+hasVar = _hasVar . desc
+
+-- |
+-- mkBoolExpr generalises a bool expression to any expression.
+mkBoolExpr :: Expr Bool -> AnyExpr
+mkBoolExpr (Expr desc eval) = AnyExpr desc (BoolFunc eval)
+
+-- |
+-- assertBool asserts that any expression is actually a bool expression.
+assertBool :: AnyExpr -> Either String (Expr Bool)
+assertBool (AnyExpr desc (BoolFunc eval)) = Right $ Expr desc eval
+assertBool (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type bool"
+
+-- |
+-- mkIntExpr generalises an int expression to any expression.
+mkIntExpr :: Expr Int -> AnyExpr
+mkIntExpr (Expr desc eval) = AnyExpr desc (IntFunc eval)
+
+-- |
+-- assertInt asserts that any expression is actually an int expression.
+assertInt :: AnyExpr -> Either String (Expr Int)
+assertInt (AnyExpr desc (IntFunc eval)) = Right $ Expr desc eval
+assertInt (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type int"
+
+-- |
+-- mkDoubleExpr generalises a double expression to any expression.
+mkDoubleExpr :: Expr Double -> AnyExpr
+mkDoubleExpr (Expr desc eval) = AnyExpr desc (DoubleFunc eval)
+
+-- |
+-- assertDouble asserts that any expression is actually a double expression.
+assertDouble :: AnyExpr -> Either String (Expr Double)
+assertDouble (AnyExpr desc (DoubleFunc eval)) = Right $ Expr desc eval
+assertDouble (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type double"
+
+-- |
+-- mkStringExpr generalises a string expression to any expression.
+mkStringExpr :: Expr Text -> AnyExpr
+mkStringExpr (Expr desc eval) = AnyExpr desc (StringFunc eval)
+
+-- |
+-- assertString asserts that any expression is actually a string expression.
+assertString :: AnyExpr -> Either String (Expr Text)
+assertString (AnyExpr desc (StringFunc eval)) = Right $ Expr desc eval
+assertString (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type string"
+
+-- |
+-- mkUintExpr generalises a uint expression to any expression.
+mkUintExpr :: Expr Word -> AnyExpr
+mkUintExpr (Expr desc eval) = AnyExpr desc (UintFunc eval)
+
+-- |
+-- assertUint asserts that any expression is actually a uint expression.
+assertUint :: AnyExpr -> Either String (Expr Word)
+assertUint (AnyExpr desc (UintFunc eval)) = Right $ Expr desc eval
+assertUint (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type uint"
+
+-- |
+-- mkBytesExpr generalises a bytes expression to any expression.
+mkBytesExpr :: Expr ByteString -> AnyExpr
+mkBytesExpr (Expr desc eval) = AnyExpr desc (BytesFunc eval)
+
+-- |
+-- assertBytes asserts that any expression is actually a bytes expression.
+assertBytes :: AnyExpr -> Either String (Expr ByteString)
+assertBytes (AnyExpr desc (BytesFunc eval)) = Right $ Expr desc eval
+assertBytes (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type bytes"
+
+-- |
+-- mkBoolsExpr generalises a list of bools expression to any expression.
+mkBoolsExpr :: Expr [Bool] -> AnyExpr
+mkBoolsExpr (Expr desc eval) = AnyExpr desc (BoolsFunc eval)
+
+-- |
+-- assertBools asserts that any expression is actually a list of bools expression.
+assertBools :: AnyExpr -> Either String (Expr [Bool])
+assertBools (AnyExpr desc (BoolsFunc eval)) = Right $ Expr desc eval
+assertBools (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type bools"
+
+-- |
+-- mkIntsExpr generalises a list of ints expression to any expression.
+mkIntsExpr :: Expr [Int] -> AnyExpr
+mkIntsExpr (Expr desc eval) = AnyExpr desc (IntsFunc eval)
+
+-- |
+-- assertInts asserts that any expression is actually a list of ints expression.
+assertInts :: AnyExpr -> Either String (Expr [Int])
+assertInts (AnyExpr desc (IntsFunc eval)) = Right $ Expr desc eval
+assertInts (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type ints"
+
+-- |
+-- mkUintsExpr generalises a list of uints expression to any expression.
+mkUintsExpr :: Expr [Word] -> AnyExpr
+mkUintsExpr (Expr desc eval) = AnyExpr desc (UintsFunc eval)
+
+-- |
+-- assertUints asserts that any expression is actually a list of uints expression.
+assertUints :: AnyExpr -> Either String (Expr [Word])
+assertUints (AnyExpr desc (UintsFunc eval)) = Right $ Expr desc eval
+assertUints (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type uints"
+
+-- |
+-- mkDoublesExpr generalises a list of doubles expression to any expression.
+mkDoublesExpr :: Expr [Double] -> AnyExpr
+mkDoublesExpr (Expr desc eval) = AnyExpr desc (DoublesFunc eval)
+
+-- |
+-- assertDoubles asserts that any expression is actually a list of doubles expression.
+assertDoubles :: AnyExpr -> Either String (Expr [Double])
+assertDoubles (AnyExpr desc (DoublesFunc eval)) = Right $ Expr desc eval
+assertDoubles (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type doubles"
+
+-- |
+-- mkStringsExpr generalises a list of strings expression to any expression.
+mkStringsExpr :: Expr [Text] -> AnyExpr
+mkStringsExpr (Expr desc eval) = AnyExpr desc (StringsFunc eval)
+
+-- |
+-- assertStrings asserts that any expression is actually a list of strings expression.
+assertStrings :: AnyExpr -> Either String (Expr [Text])
+assertStrings (AnyExpr desc (StringsFunc eval)) = Right $ Expr desc eval
+assertStrings (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type strings"
+
+-- |
+-- mkListOfBytesExpr generalises a list of bytes expression to any expression.
+mkListOfBytesExpr :: Expr [ByteString] -> AnyExpr
+mkListOfBytesExpr (Expr desc eval) = AnyExpr desc (ListOfBytesFunc eval)
+
+-- |
+-- assertListOfBytes asserts that any expression is actually a list of bytes expression.
+assertListOfBytes :: AnyExpr -> Either String (Expr [ByteString])
+assertListOfBytes (AnyExpr desc (ListOfBytesFunc eval)) = Right $ Expr desc eval
+assertListOfBytes (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type bytes"
+
+-- cmp is an efficient comparison function for expressions.
+-- It is very important that cmp is efficient, 
+-- because it is a bottleneck for simplification and smart construction of large queries.
+cmp :: Desc -> Desc -> Ordering
+cmp a b = compare (_hash a) (_hash b) <>
+    compare (_name a) (_name b) <>
+    compare (length (_params a)) (length (_params b)) <>
+    foldl (<>) EQ (zipWith cmp (_params a) (_params b)) <>
+    compare (_toStr a) (_toStr b)
+
+-- |
+-- hashWithName calculates a hash of the function name and its parameters.
+hashWithName :: String -> [Desc] -> Int
+hashWithName s ds = hashList (31*17 + hashString s) (map _hash ds)
+
+-- |
+-- hashString calcuates a hash of a string.
+hashString :: String -> Int
+hashString s = hashList 0 (map ord s)
+
+-- |
+-- hashList folds a list of hashes into one, given a seed and the list.
+hashList :: Int -> [Int] -> Int
+hashList = foldl (\acc h -> 31*acc + h)
+
+noLabel :: Parser.Label
+noLabel = Parser.String (pack "not a label, trying constant evaluation")
+
+-- |
+-- evalConst tries to evaluate a constant expression and 
+-- either returns the resulting constant value or nothing.
+evalConst :: Expr a -> Maybe a
+evalConst e = if hasVar e
+    then Nothing
+    else case eval e noLabel of
+        (Left _) -> Nothing
+        (Right v) -> Just v
+
+-- |
+-- isConst returns whether the input description is one of the six possible constant values.
+isConst :: Desc -> Bool
+isConst d = not (null (_params d)) && case _name d of
+    "bool" -> True
+    "int" -> True
+    "uint" -> True
+    "double" -> True
+    "string" -> True
+    "[]byte" -> True
+    _ -> False
+
+-- |
+-- boolExpr creates a constant bool expression from a input value.
+boolExpr :: Bool -> Expr Bool 
+boolExpr b = Expr {
+    desc = Desc {
+        _name = "bool"
+        , _toStr = if b then "true" else "false"
+        , _hash = if b then 3 else 5
+        , _params = []
+        , _hasVar = False
+    }
+    , eval = const $ return b
+}
+
+-- |
+-- intExpr creates a constant int expression from a input value.
+intExpr :: Int -> Expr Int
+intExpr i = Expr {
+    desc = Desc {
+        _name = "int"
+        , _toStr = show i
+        , _hash = i
+        , _params = []
+        , _hasVar = False
+    }
+    , eval = const $ return i
+}
+
+-- |
+-- doubleExpr creates a constant double expression from a input value.
+doubleExpr :: Double -> Expr Double
+doubleExpr d = Expr {
+    desc = Desc {
+        _name = "double"
+        , _toStr = show d
+        , _hash = truncate d
+        , _params = []
+        , _hasVar = False
+    }
+    , eval = const $ return d
+}
+
+-- |
+-- uintExpr creates a constant uint expression from a input value.
+uintExpr :: Word -> Expr Word
+uintExpr i = Expr {
+    desc = Desc {
+        _name = "uint"
+        , _toStr = show i
+        , _hash = hashString (show i)
+        , _params = []
+        , _hasVar = False
+    }
+    , eval = const $ return i
+}
+
+-- |
+-- stringExpr creates a constant string expression from a input value.
+stringExpr :: Text -> Expr Text
+stringExpr s = Expr {
+    desc = Desc {
+        _name = "string"
+        , _toStr = show s
+        , _hash = hashString (unpack s)
+        , _params = []
+        , _hasVar = False
+    }
+    , eval = const $ return s
+}
+
+-- |
+-- bytesExpr creates a constant bytes expression from a input value.
+bytesExpr :: ByteString -> Expr ByteString
+bytesExpr b = Expr {
+    desc = Desc {
+        _name = "bytes"
+        , _toStr = "[]byte{" ++ show b ++ "}"
+        , _hash = hashString (show b)
+        , _params = []
+        , _hasVar = False
+    }
+    , eval = const $ return b
+}
+
+-- |
+-- trimBool tries to reduce an expression to a single constant expression,
+-- if it does not contain a variable.
+trimBool :: Expr Bool -> Expr Bool
+trimBool e = if hasVar e 
+    then e
+    else case eval e noLabel of
+        (Left _) -> e
+        (Right v) -> boolExpr v
+
+-- |
+-- trimInt tries to reduce an expression to a single constant expression,
+-- if it does not contain a variable.
+trimInt :: Expr Int -> Expr Int
+trimInt e = if hasVar e 
+    then e
+    else case eval e noLabel of
+        (Left _) -> e
+        (Right v) -> intExpr v
+
+-- |
+-- trimUint tries to reduce an expression to a single constant expression,
+-- if it does not contain a variable.
+trimUint :: Expr Word -> Expr Word
+trimUint e = if hasVar e 
+    then e
+    else case eval e noLabel of
+        (Left _) -> e
+        (Right v) -> uintExpr v
+
+-- |
+-- trimString tries to reduce an expression to a single constant expression,
+-- if it does not contain a variable.
+trimString :: Expr Text -> Expr Text
+trimString e = if hasVar e 
+    then e
+    else case eval e noLabel of
+        (Left _) -> e
+        (Right v) -> stringExpr v
+
+-- |
+-- trimDouble tries to reduce an expression to a single constant expression,
+-- if it does not contain a variable.
+trimDouble :: Expr Double -> Expr Double
+trimDouble e = if hasVar e 
+    then e
+    else case eval e noLabel of
+        (Left _) -> e
+        (Right v) -> doubleExpr v
+
+-- |
+-- trimBytes tries to reduce an expression to a single constant expression,
+-- if it does not contain a variable.
+trimBytes :: Expr ByteString -> Expr ByteString
+trimBytes e = if hasVar e 
+    then e
+    else case eval e noLabel of
+        (Left _) -> e
+        (Right v) -> bytesExpr v
+
+-- |
+-- boolsExpr sequences a list of expressions that each return a bool, 
+-- to a single expression that returns a list of bools.
+boolsExpr :: [Expr Bool] -> Expr [Bool]
+boolsExpr = seqExprs "[]bool" 
+
+-- |
+-- intsExpr sequences a list of expressions that each return an int, 
+-- to a single expression that returns a list of ints.
+intsExpr :: [Expr Int] -> Expr [Int]
+intsExpr = seqExprs "[]int"
+
+-- |
+-- stringsExpr sequences a list of expressions that each return a string, 
+-- to a single expression that returns a list of strings.
+stringsExpr :: [Expr Text] -> Expr [Text]
+stringsExpr = seqExprs "[]string"
+
+-- |
+-- doublesExpr sequences a list of expressions that each return a double, 
+-- to a single expression that returns a list of doubles.
+doublesExpr :: [Expr Double] -> Expr [Double]
+doublesExpr = seqExprs "[]double"
+
+-- |
+-- listOfBytesExpr sequences a list of expressions that each return bytes, 
+-- to a single expression that returns a list of bytes.
+listOfBytesExpr :: [Expr ByteString] -> Expr [ByteString]
+listOfBytesExpr = seqExprs "[][]byte"
+
+-- |
+-- uintsExpr sequences a list of expressions that each return a uint, 
+-- to a single expression that returns a list of uints.
+uintsExpr :: [Expr Word] -> Expr [Word]
+uintsExpr = seqExprs "[]uint"
+
+seqExprs :: String -> [Expr a] -> Expr [a]
+seqExprs n es = Expr {
+    desc = mkDesc n (map desc es)
+    , eval = \v -> mapM (`eval` v) es
+}
diff --git a/src/Data/Katydid/Relapse/Exprs.hs b/src/Data/Katydid/Relapse/Exprs.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Exprs.hs
@@ -0,0 +1,86 @@
+-- |
+-- This module contains the standard library of expressions, used by the Relapse parser.
+
+module Data.Katydid.Relapse.Exprs (
+    mkBuiltIn
+    , mkExpr
+    , MkFunc
+    , stdOnly
+) where
+
+import Data.Katydid.Relapse.Expr
+import Data.Katydid.Relapse.Exprs.Compare
+import Data.Katydid.Relapse.Exprs.Contains
+import Data.Katydid.Relapse.Exprs.Elem
+import Data.Katydid.Relapse.Exprs.Length
+import Data.Katydid.Relapse.Exprs.Logic
+import Data.Katydid.Relapse.Exprs.Strings
+import Data.Katydid.Relapse.Exprs.Type
+import Data.Katydid.Relapse.Exprs.Var
+
+-- |
+-- MkFunc is used by the parser to create a function from a name and arguments.
+type MkFunc = String -> [AnyExpr] -> Either String AnyExpr
+
+-- |
+-- mkExpr is a grouping of all the standard library functions as one MkFunc.
+mkExpr :: String -> [AnyExpr] -> Either String AnyExpr
+mkExpr "eq" es = mkEqExpr es
+mkExpr "ne" es = mkNeExpr es
+mkExpr "ge" es = mkGeExpr es
+mkExpr "gt" es = mkGtExpr es
+mkExpr "le" es = mkLeExpr es
+mkExpr "lt" es = mkLtExpr es
+mkExpr "contains" es = mkContainsExpr es
+mkExpr "elem" es = mkElemExpr es
+mkExpr "length" es = mkLengthExpr es
+mkExpr "not" es = mkNotExpr es
+mkExpr "and" es = mkAndExpr es
+mkExpr "or" es = mkOrExpr es
+mkExpr "hasPrefix" es = mkHasPrefixExpr es
+mkExpr "hasSuffix" es = mkHasSuffixExpr es
+mkExpr "regex" es = mkRegexExpr es
+mkExpr "toLower" es = mkToLowerExpr es
+mkExpr "toUpper" es = mkToUpperExpr es
+mkExpr "type" es = mkTypeExpr es
+mkExpr n _ = Left $ "unknown function: " ++ n
+
+-- |
+-- stdOnly contains no functions, which means that when it is combined 
+-- (in Relapse parser) with mkExpr the parser will have access to only the standard library.
+stdOnly :: String -> [AnyExpr] -> Either String AnyExpr
+stdOnly n _ = Left $ "unknown function: " ++ n
+
+-- |
+-- mkBuiltIn parsers a builtin function to a relapse expression.
+mkBuiltIn :: String -> AnyExpr -> Either String AnyExpr
+mkBuiltIn symbol constExpr = funcName symbol >>= (\n ->
+        if n == "type" then
+            mkExpr n [constExpr]
+        else if n == "regex" then
+            mkExpr n [constExpr, constToVar constExpr]
+        else
+            mkExpr n [constToVar constExpr, constExpr]
+    )
+
+funcName :: String -> Either String String
+funcName "==" = return "eq"
+funcName "!=" = return "ne"
+funcName "<" = return "lt"
+funcName ">" = return "gt"
+funcName "<=" = return "le"
+funcName ">=" = return "ge"
+funcName "~=" = return "regex"
+funcName "*=" = return "contains"
+funcName "^=" = return "hasPrefix"
+funcName "$=" = return "hasSuffix"
+funcName "::" = return "type"
+funcName n = fail $ "unexpected funcName: <" ++ n ++ ">"
+
+constToVar :: AnyExpr -> AnyExpr
+constToVar (AnyExpr _ (BoolFunc _)) = mkBoolExpr varBoolExpr
+constToVar (AnyExpr _ (IntFunc _)) = mkIntExpr varIntExpr
+constToVar (AnyExpr _ (UintFunc _)) = mkUintExpr varUintExpr
+constToVar (AnyExpr _ (DoubleFunc _)) = mkDoubleExpr varDoubleExpr
+constToVar (AnyExpr _ (StringFunc _)) = mkStringExpr varStringExpr
+constToVar (AnyExpr _ (BytesFunc _)) = mkBytesExpr varBytesExpr
diff --git a/src/Data/Katydid/Relapse/Exprs/Compare.hs b/src/Data/Katydid/Relapse/Exprs/Compare.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Exprs/Compare.hs
@@ -0,0 +1,191 @@
+-- |
+-- This module contains the Relapse compare expressions: 
+-- equal, not equal, greater than, greater than or equal, less than and less than or equal.
+module Data.Katydid.Relapse.Exprs.Compare (
+    mkEqExpr, eqExpr
+    , mkNeExpr, neExpr
+    , mkGeExpr, geExpr
+    , mkLeExpr, leExpr
+    , mkGtExpr, gtExpr
+    , mkLtExpr, ltExpr
+) where
+
+import Data.Katydid.Relapse.Expr
+
+-- |
+-- mkEqExpr dynamically creates an eq (equal) expression, if the two input types are the same.
+mkEqExpr :: [AnyExpr] -> Either String AnyExpr
+mkEqExpr es = do {
+    (e1, e2) <- assertArgs2 "eq" es;
+    case e1 of
+    (AnyExpr _ (BoolFunc _)) -> mkEqExpr' <$> assertBool e1 <*> assertBool e2
+    (AnyExpr _ (IntFunc _)) -> mkEqExpr' <$> assertInt e1 <*> assertInt e2
+    (AnyExpr _ (UintFunc _)) ->  mkEqExpr' <$> assertUint e1 <*> assertUint e2
+    (AnyExpr _ (DoubleFunc _)) -> mkEqExpr' <$> assertDouble e1 <*> assertDouble e2
+    (AnyExpr _ (StringFunc _)) -> mkEqExpr' <$> assertString e1 <*> assertString e2
+    (AnyExpr _ (BytesFunc _)) -> mkEqExpr' <$> assertBytes e1 <*> assertBytes e2
+}
+
+mkEqExpr' :: (Eq a) => Expr a -> Expr a -> AnyExpr
+mkEqExpr' e f = mkBoolExpr $ eqExpr e f
+
+-- |
+-- eqExpr creates an eq (equal) expression that returns true if the two evaluated input expressions are equal
+-- and both don't evaluate to an error.
+eqExpr :: (Eq a) => Expr a -> Expr a -> Expr Bool
+eqExpr a b = trimBool Expr {
+    desc = mkDesc "eq" [desc a, desc b]
+    , eval = \v -> eq (eval a v) (eval b v)
+}
+
+eq :: (Eq a) => Either String a -> Either String a -> Either String Bool
+eq (Right v1) (Right v2) = return $ v1 == v2
+eq (Left _) _ = return False
+eq _ (Left _) = return False
+
+-- |
+-- mkNeExpr dynamically creates a ne (not equal) expression, if the two input types are the same.
+mkNeExpr :: [AnyExpr] -> Either String AnyExpr
+mkNeExpr es = do {
+    (e1, e2) <- assertArgs2 "ne" es;
+    case e1 of
+    (AnyExpr _ (BoolFunc _)) -> mkNeExpr' <$> assertBool e1 <*> assertBool e2
+    (AnyExpr _ (IntFunc _)) -> mkNeExpr' <$> assertInt e1 <*> assertInt e2
+    (AnyExpr _ (UintFunc _)) ->  mkNeExpr' <$> assertUint e1 <*> assertUint e2
+    (AnyExpr _ (DoubleFunc _)) -> mkNeExpr' <$> assertDouble e1 <*> assertDouble e2
+    (AnyExpr _ (StringFunc _)) -> mkNeExpr' <$> assertString e1 <*> assertString e2
+    (AnyExpr _ (BytesFunc _)) -> mkNeExpr' <$> assertBytes e1 <*> assertBytes e2
+}
+
+mkNeExpr' :: (Eq a) => Expr a -> Expr a -> AnyExpr
+mkNeExpr' e f = mkBoolExpr $ neExpr e f
+
+-- |
+-- neExpr creates a ne (not equal) expression that returns true if the two evaluated input expressions are not equal
+-- and both don't evaluate to an error.
+neExpr :: (Eq a) => Expr a -> Expr a -> Expr Bool
+neExpr a b = trimBool Expr {
+    desc = mkDesc "ne" [desc a, desc b]
+    , eval = \v -> ne (eval a v) (eval b v)
+}
+
+ne :: (Eq a) => Either String a -> Either String a -> Either String Bool
+ne (Right v1) (Right v2) = return $ v1 /= v2
+ne (Left _) _ = return False
+ne _ (Left _) = return False
+
+-- |
+-- mkGeExpr dynamically creates a ge (greater than or equal) expression, if the two input types are the same.
+mkGeExpr :: [AnyExpr] -> Either String AnyExpr
+mkGeExpr es = do {
+    (e1, e2) <- assertArgs2 "ge" es;
+    case e1 of
+    (AnyExpr _ (IntFunc _)) -> mkGeExpr' <$> assertInt e1 <*> assertInt e2
+    (AnyExpr _ (UintFunc _)) ->  mkGeExpr' <$> assertUint e1 <*> assertUint e2
+    (AnyExpr _ (DoubleFunc _)) -> mkGeExpr' <$> assertDouble e1 <*> assertDouble e2
+    (AnyExpr _ (BytesFunc _)) -> mkGeExpr' <$> assertBytes e1 <*> assertBytes e2
+}
+
+mkGeExpr' :: (Ord a) => Expr a -> Expr a -> AnyExpr
+mkGeExpr' e f = mkBoolExpr $ geExpr e f
+
+-- |
+-- geExpr creates a ge (greater than or equal) expression that returns true if the first evaluated expression is greater than or equal to the second
+-- and both don't evaluate to an error.
+geExpr :: (Ord a) => Expr a -> Expr a -> Expr Bool
+geExpr a b = trimBool Expr {
+    desc = mkDesc "ge" [desc a, desc b]
+    , eval = \v -> ge (eval a v) (eval b v)
+}
+
+ge :: (Ord a) => Either String a -> Either String a -> Either String Bool
+ge (Right v1) (Right v2) = return $ v1 >= v2
+ge (Left _) _ = return False
+ge _ (Left _) = return False
+
+-- |
+-- mkGtExpr dynamically creates a gt (greater than) expression, if the two input types are the same.
+mkGtExpr :: [AnyExpr] -> Either String AnyExpr
+mkGtExpr es = do {
+    (e1, e2) <- assertArgs2 "gt" es;
+    case e1 of
+    (AnyExpr _ (IntFunc _)) -> mkGtExpr' <$> assertInt e1 <*> assertInt e2
+    (AnyExpr _ (UintFunc _)) ->  mkGtExpr' <$> assertUint e1 <*> assertUint e2
+    (AnyExpr _ (DoubleFunc _)) -> mkGtExpr' <$> assertDouble e1 <*> assertDouble e2
+    (AnyExpr _ (BytesFunc _)) -> mkGtExpr' <$> assertBytes e1 <*> assertBytes e2
+}
+
+mkGtExpr' :: (Ord a) => Expr a -> Expr a -> AnyExpr
+mkGtExpr' e f = mkBoolExpr $ gtExpr e f
+
+-- |
+-- gtExpr creates a gt (greater than) expression that returns true if the first evaluated expression is greater than the second
+-- and both don't evaluate to an error.
+gtExpr :: (Ord a) => Expr a -> Expr a -> Expr Bool
+gtExpr a b = trimBool Expr {
+    desc = mkDesc "gt" [desc a, desc b]
+    , eval = \v -> gt (eval a v) (eval b v)
+}
+
+gt :: (Ord a) => Either String a -> Either String a -> Either String Bool
+gt (Right v1) (Right v2) = return $ v1 > v2
+gt (Left _) _ = return False
+gt _ (Left _) = return False
+
+-- |
+-- mkLeExpr dynamically creates a le (less than or equal) expression, if the two input types are the same.
+mkLeExpr :: [AnyExpr] -> Either String AnyExpr
+mkLeExpr es = do {
+    (e1, e2) <- assertArgs2 "le" es;
+    case e1 of
+    (AnyExpr _ (IntFunc _)) -> mkLeExpr' <$> assertInt e1 <*> assertInt e2
+    (AnyExpr _ (UintFunc _)) ->  mkLeExpr' <$> assertUint e1 <*> assertUint e2
+    (AnyExpr _ (DoubleFunc _)) -> mkLeExpr' <$> assertDouble e1 <*> assertDouble e2
+    (AnyExpr _ (BytesFunc _)) -> mkLeExpr' <$> assertBytes e1 <*> assertBytes e2
+}
+
+mkLeExpr' :: (Ord a) => Expr a -> Expr a -> AnyExpr
+mkLeExpr' e f = mkBoolExpr $ leExpr e f
+
+-- |
+-- leExpr creates a le (less than or equal) expression that returns true if the first evaluated expression is less than or equal to the second
+-- and both don't evaluate to an error.
+leExpr :: (Ord a) => Expr a -> Expr a -> Expr Bool
+leExpr a b = trimBool Expr {
+    desc = mkDesc "le" [desc a, desc b]
+    , eval = \v -> le (eval a v) (eval b v)
+}
+
+le :: (Ord a) => Either String a -> Either String a -> Either String Bool
+le (Right v1) (Right v2) = return $ v1 <= v2
+le (Left _) _ = return False
+le _ (Left _) = return False
+
+-- |
+-- mkLtExpr dynamically creates a lt (less than) expression, if the two input types are the same.
+mkLtExpr :: [AnyExpr] -> Either String AnyExpr
+mkLtExpr es = do {
+    (e1, e2) <- assertArgs2 "lt" es;
+    case e1 of
+    (AnyExpr _ (IntFunc _)) -> mkLtExpr' <$> assertInt e1 <*> assertInt e2
+    (AnyExpr _ (UintFunc _)) ->  mkLtExpr' <$> assertUint e1 <*> assertUint e2
+    (AnyExpr _ (DoubleFunc _)) -> mkLtExpr' <$> assertDouble e1 <*> assertDouble e2
+    (AnyExpr _ (BytesFunc _)) -> mkLtExpr' <$> assertBytes e1 <*> assertBytes e2
+}
+
+mkLtExpr' :: (Ord a) => Expr a -> Expr a -> AnyExpr
+mkLtExpr' e f = mkBoolExpr $ ltExpr e f
+
+-- |
+-- ltExpr creates a lt (less than) expression that returns true if the first evaluated expression is less than the second
+-- and both don't evaluate to an error.
+ltExpr :: (Ord a) => Expr a -> Expr a -> Expr Bool
+ltExpr a b = trimBool Expr {
+    desc = mkDesc "lt" [desc a, desc b]
+    , eval = \v -> lt (eval a v) (eval b v)
+}
+
+lt :: (Ord a) => Either String a -> Either String a -> Either String Bool
+lt (Right v1) (Right v2) = return $ v1 < v2
+lt (Left _) _ = return False
+lt _ (Left _) = return False
diff --git a/src/Data/Katydid/Relapse/Exprs/Contains.hs b/src/Data/Katydid/Relapse/Exprs/Contains.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Exprs/Contains.hs
@@ -0,0 +1,48 @@
+-- |
+-- This module contains the Relapse contains expressions.
+module Data.Katydid.Relapse.Exprs.Contains (
+    mkContainsExpr
+    , containsStringExpr
+    , containsExpr
+) where
+
+import qualified Data.Text as Text
+
+import Data.Katydid.Relapse.Expr
+
+-- |
+-- mkContainsExpr dynamically creates a contains expression, if the two input types are:
+-- 
+--     * String and String where the second string is the possible substring.
+--     * A List of :Strings, Ints or Uints paired with a String, Int or Uint respectively.
+mkContainsExpr :: [AnyExpr] -> Either String AnyExpr
+mkContainsExpr es = do {
+    (e1, e2) <- assertArgs2 "contains" es;
+    case e2 of
+    (AnyExpr _ (StringFunc _)) -> mkContainsStringExpr' <$> assertString e1 <*> assertString e2
+    (AnyExpr _ (StringsFunc _)) -> mkContainsExpr' <$> assertString e1 <*> assertStrings e2
+    (AnyExpr _ (IntsFunc _)) -> mkContainsExpr' <$> assertInt e1 <*> assertInts e2
+    (AnyExpr _ (UintsFunc _)) -> mkContainsExpr' <$> assertUint e1 <*> assertUints e2
+}
+
+mkContainsStringExpr' :: Expr Text.Text -> Expr Text.Text -> AnyExpr
+mkContainsStringExpr' e f = mkBoolExpr $ containsStringExpr e f
+
+-- |
+-- containsStringExpr creates a contains expression that returns true if the second string is a substring of the first.
+containsStringExpr :: Expr Text.Text -> Expr Text.Text -> Expr Bool
+containsStringExpr s sub = trimBool Expr {
+    desc = mkDesc "contains" [desc s, desc sub]
+    , eval = \v -> Text.isInfixOf <$> eval sub v <*> eval s v
+}
+
+mkContainsExpr' :: (Eq a) => Expr a -> Expr [a] -> AnyExpr
+mkContainsExpr' e f = mkBoolExpr $ containsExpr e f
+
+-- |
+-- containsExpr creates a contains expression that returns true if the first argument is an element in the second list argument.
+containsExpr :: (Eq a) => Expr a -> Expr [a] -> Expr Bool
+containsExpr e es = trimBool Expr {
+    desc = mkDesc "contains" [desc e, desc es]
+    , eval = \v -> elem <$> eval e v <*> eval es v
+}
diff --git a/src/Data/Katydid/Relapse/Exprs/Elem.hs b/src/Data/Katydid/Relapse/Exprs/Elem.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Exprs/Elem.hs
@@ -0,0 +1,35 @@
+-- |
+-- This module contains the Relapse elem expression.
+module Data.Katydid.Relapse.Exprs.Elem (
+    mkElemExpr
+    , elemExpr
+) where
+
+import Data.Katydid.Relapse.Expr
+
+-- |
+-- mkElemExpr dynamically creates an elem expression, if the first argument is a list and the second an int index.
+mkElemExpr :: [AnyExpr] -> Either String AnyExpr
+mkElemExpr es = do {
+    (e1, e2) <- assertArgs2 "elem" es;
+    case e1 of
+    (AnyExpr _ (BoolsFunc _)) -> mkElemExpr' mkBoolExpr <$> assertBools e1 <*> assertInt e2
+    (AnyExpr _ (IntsFunc _)) -> mkElemExpr' mkIntExpr <$> assertInts e1 <*> assertInt e2
+    (AnyExpr _ (UintsFunc _)) -> mkElemExpr' mkUintExpr <$> assertUints e1 <*> assertInt e2
+    (AnyExpr _ (DoublesFunc _)) -> mkElemExpr' mkDoubleExpr <$> assertDoubles e1 <*> assertInt e2
+    (AnyExpr _ (StringsFunc _)) -> mkElemExpr' mkStringExpr <$> assertStrings e1 <*> assertInt e2
+    (AnyExpr _ (ListOfBytesFunc _)) -> mkElemExpr' mkBytesExpr <$> assertListOfBytes e1 <*> assertInt e2
+}
+
+mkElemExpr' :: (Expr a -> AnyExpr) -> Expr [a] -> Expr Int -> AnyExpr
+mkElemExpr' mk list index =  mk $ elemExpr list index
+
+-- | 
+-- elemExpr creates an expression that returns an element from the list at the specified index.
+-- Trimming this function would cause it to become non generic.
+-- It is not necessary to trim each function, since it is just an optimization.
+elemExpr :: Expr [a] -> Expr Int -> Expr a
+elemExpr a b = Expr {
+    desc = mkDesc "elem" [desc a, desc b]
+    , eval = \v -> (!!) <$> eval a v <*> eval b v
+}
diff --git a/src/Data/Katydid/Relapse/Exprs/Length.hs b/src/Data/Katydid/Relapse/Exprs/Length.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Exprs/Length.hs
@@ -0,0 +1,54 @@
+-- |
+-- This module contains the Relapse length expressions.
+module Data.Katydid.Relapse.Exprs.Length (
+    mkLengthExpr
+    , lengthListExpr
+    , lengthStringExpr
+    , lengthBytesExpr
+) where
+
+import qualified Data.Text as Text
+import qualified Data.ByteString as ByteString
+
+import Data.Katydid.Relapse.Expr
+
+-- |
+-- mkLengthExpr dynamically creates a length expression, if the single argument is a list, string or bytes.
+mkLengthExpr :: [AnyExpr] -> Either String AnyExpr
+mkLengthExpr es = do {
+    e <- assertArgs1 "length" es;
+    case e of
+    (AnyExpr _ (BoolsFunc _)) -> mkIntExpr . lengthListExpr <$> assertBools e;
+    (AnyExpr _ (IntsFunc _)) -> mkIntExpr . lengthListExpr <$> assertInts e;
+    (AnyExpr _ (UintsFunc _)) -> mkIntExpr . lengthListExpr <$> assertUints e;
+    (AnyExpr _ (DoublesFunc _)) -> mkIntExpr . lengthListExpr <$> assertDoubles e;
+    (AnyExpr _ (StringsFunc _)) -> mkIntExpr . lengthListExpr <$> assertStrings e;
+    (AnyExpr _ (ListOfBytesFunc _)) -> mkIntExpr . lengthListExpr <$> assertListOfBytes e;
+    (AnyExpr _ (StringFunc _)) -> mkIntExpr . lengthStringExpr <$> assertString e;
+    (AnyExpr _ (BytesFunc _)) -> mkIntExpr . lengthBytesExpr <$> assertBytes e;
+}
+
+-- |
+-- lengthListExpr creates a length expression, that returns the length of a list.
+lengthListExpr :: Expr [a] -> Expr Int
+lengthListExpr e = trimInt Expr {
+    desc = mkDesc "length" [desc e]
+    , eval = \v -> length <$> eval e v
+}
+
+-- |
+-- lengthStringExpr creates a length expression, that returns the length of a string.
+lengthStringExpr :: Expr Text.Text -> Expr Int
+lengthStringExpr e = trimInt Expr {
+    desc = mkDesc "length" [desc e]
+    , eval = \v -> Text.length <$> eval e v
+}
+
+-- |
+-- lengthBytesExpr creates a length expression, that returns the length of bytes.
+lengthBytesExpr :: Expr ByteString.ByteString -> Expr Int
+lengthBytesExpr e = trimInt Expr {
+    desc = mkDesc "length" [desc e]
+    , eval = \v -> ByteString.length <$> eval e v
+}
+
diff --git a/src/Data/Katydid/Relapse/Exprs/Logic.hs b/src/Data/Katydid/Relapse/Exprs/Logic.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Exprs/Logic.hs
@@ -0,0 +1,128 @@
+-- |
+-- This module contains the Relapse logic expressions: not, and, or. 
+module Data.Katydid.Relapse.Exprs.Logic (
+    mkNotExpr, notExpr
+    , mkAndExpr, andExpr
+    , mkOrExpr, orExpr
+) where
+
+import Data.Katydid.Relapse.Expr
+import Data.Katydid.Relapse.Exprs.Var
+
+-- |
+-- mkNotExpr dynamically creates a not expression, if the single argument is a bool expression.
+mkNotExpr :: [AnyExpr] -> Either String AnyExpr
+mkNotExpr es = do {
+    e <- assertArgs1 "not" es;
+    b <- assertBool e;
+    return $ mkBoolExpr (notExpr b);
+}
+
+-- |
+-- notExpr creates a not expression, that returns true is the argument expression returns an error or false.
+notExpr :: Expr Bool -> Expr Bool
+notExpr e = trimBool Expr {
+    desc = notDesc (desc e)
+    , eval = \v -> case eval e v of
+        (Left _) -> return True
+        (Right b) -> return $ not b
+}
+
+-- notDesc superficially pushes not operators down to normalize functions.
+-- Normalizing functions increases the chances of finding equal expressions and being able to simplify patterns.
+notDesc :: Desc -> Desc
+notDesc d
+    | _name d == "not" = 
+        let child0 = head $ _params d
+        in mkDesc (_name child0) (_params child0)
+    | _name d == "and" =
+        let [left, right] = _params d
+        in mkDesc "or" [mkDesc "not" [left], mkDesc "not" [right]]
+    | _name d == "or" =
+        let [left, right] = _params d
+        in mkDesc "and" [mkDesc "not" [left], mkDesc "not" [right]]
+    | _name d == "ne" = mkDesc "eq" $  _params d
+    | _name d == "eq" = mkDesc "ne" $ _params d
+    | otherwise = mkDesc "not" [d]
+
+-- |
+-- mkAndExpr dynamically creates an and expression, if the two arguments are both bool expressions.
+mkAndExpr :: [AnyExpr] -> Either String AnyExpr
+mkAndExpr es = do {
+    (e1, e2) <- assertArgs2 "and" es;
+    b1 <- assertBool e1;
+    b2 <- assertBool e2;
+    return $ mkBoolExpr $ andExpr b1 b2;
+}
+
+-- |
+-- andExpr creates an and expression that returns true if both arguments are true.
+andExpr :: Expr Bool -> Expr Bool -> Expr Bool
+andExpr a b = case (evalConst a, evalConst b) of
+    (Just False, _) -> boolExpr False
+    (_, Just False) -> boolExpr False
+    (Just True, _) -> b
+    (_, Just True) -> a
+    _ -> andExpr' a b
+
+-- andExpr' creates an `and` expression, but assumes that both expressions have a var.
+andExpr' :: Expr Bool -> Expr Bool -> Expr Bool
+andExpr' a b
+    | a == b = a
+    | name a == "not" && head (params a) == desc b = boolExpr False
+    | name b == "not" && head (params b) == desc a = boolExpr False
+    | name a == "eq" && name b == "eq" = case (varAndConst a, varAndConst b) of
+        (Just ca, Just cb) -> if ca == cb then a else boolExpr False
+        _ -> defaultAnd a b
+    | name a == "eq" && name b == "ne" = case (varAndConst a, varAndConst b) of
+        (Just ca, Just cb) -> if ca == cb then boolExpr False else a
+        _ -> defaultAnd a b
+    | name a == "ne" && name b == "eq" = case (varAndConst a, varAndConst b) of
+        (Just ca, Just cb) -> if ca == cb then boolExpr False else b
+        _ -> defaultAnd a b
+    | otherwise = defaultAnd a b
+
+defaultAnd :: Expr Bool -> Expr Bool -> Expr Bool
+defaultAnd a b = Expr {
+    desc = mkDesc "and" [desc a, desc b]
+    , eval = \v -> (&&) <$> eval a v <*> eval b v
+}
+
+varAndConst :: Expr Bool -> Maybe Desc
+varAndConst e = let ps = params e
+    in if length ps /= 2 then Nothing
+    else let [a,b] = ps in
+        if isVar a && isConst b then Just b
+        else if isVar b && isConst a then Just a
+        else Nothing
+
+-- |
+-- mkOrExpr dynamically creates an or expression, if the two arguments are both bool expressions.
+mkOrExpr :: [AnyExpr] -> Either String AnyExpr
+mkOrExpr es = do {
+    (e1, e2) <- assertArgs2 "or" es;
+    b1 <- assertBool e1;
+    b2 <- assertBool e2;
+    return $ mkBoolExpr $ orExpr b1 b2;
+}
+
+-- |
+-- orExpr creates an or expression that returns true if either argument is true.
+orExpr :: Expr Bool -> Expr Bool -> Expr Bool
+orExpr a b = case (evalConst a, evalConst b) of
+    (Just True, _) -> boolExpr True
+    (_, Just True) -> boolExpr True
+    (Just False, _) -> b
+    (_, Just False) -> a
+    _ -> orExpr' a b
+
+-- orExpr' creates an `or` expression, but assumes that both expressions have a var.
+orExpr' :: Expr Bool -> Expr Bool -> Expr Bool
+orExpr' a b
+    | a == b = a
+    | name a == "not" && head (params a) == desc b = boolExpr True
+    | name b == "not" && head (params b) == desc a = boolExpr True
+    | otherwise = Expr {
+        desc = mkDesc "or" [desc a, desc b]
+        , eval = \v -> (||) <$> eval a v <*> eval b v
+    }
diff --git a/src/Data/Katydid/Relapse/Exprs/Strings.hs b/src/Data/Katydid/Relapse/Exprs/Strings.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Exprs/Strings.hs
@@ -0,0 +1,107 @@
+-- |
+-- This module contains the Relapse string expressions.
+
+module Data.Katydid.Relapse.Exprs.Strings (
+    mkHasPrefixExpr, hasPrefixExpr
+    , mkHasSuffixExpr, hasSuffixExpr
+    , mkRegexExpr, regexExpr
+    , mkToLowerExpr, toLowerExpr
+    , mkToUpperExpr, toUpperExpr
+) where
+
+import Text.Regex.TDFA ((=~))
+import Data.Text (Text, isPrefixOf, isSuffixOf, toLower, toUpper, unpack)
+
+import Data.Katydid.Relapse.Expr
+
+-- |
+-- mkHasPrefixExpr dynamically creates a hasPrefix expression.
+mkHasPrefixExpr :: [AnyExpr] -> Either String AnyExpr
+mkHasPrefixExpr es = do {
+    (e1, e2) <- assertArgs2 "hasPrefix" es;
+    s1 <- assertString e1;
+    s2 <- assertString e2;
+    return $ mkBoolExpr $ hasPrefixExpr s1 s2;
+}
+
+-- |
+-- hasPrefixExpr creates a hasPrefix expression that returns true if the second is a prefix of the first.
+hasPrefixExpr :: Expr Text -> Expr Text -> Expr Bool
+hasPrefixExpr e1 e2 = trimBool Expr {
+    desc = mkDesc "hasPrefix" [desc e1, desc e2]
+    , eval = \v -> isPrefixOf <$> eval e2 v <*> eval e1 v
+}
+
+-- |
+-- mkHasSuffixExpr dynamically creates a hasSuffix expression.
+mkHasSuffixExpr :: [AnyExpr] -> Either String AnyExpr
+mkHasSuffixExpr es = do {
+    (e1, e2) <- assertArgs2 "hasSuffix" es;
+    s1 <- assertString e1;
+    s2 <- assertString e2;
+    return $ mkBoolExpr $ hasSuffixExpr s1 s2;
+}
+
+-- |
+-- hasSuffixExpr creates a hasSuffix expression that returns true if the second is a suffix of the first.
+hasSuffixExpr :: Expr Text -> Expr Text -> Expr Bool
+hasSuffixExpr e1 e2 = trimBool Expr {
+    desc = mkDesc "hasSuffix" [desc e1, desc e2]
+    , eval = \v -> isSuffixOf <$> eval e2 v <*> eval e1 v
+}
+
+-- |
+-- mkRegexExpr dynamically creates a regex expression.
+mkRegexExpr :: [AnyExpr] -> Either String AnyExpr
+mkRegexExpr es = do {
+    (e1, e2) <- assertArgs2 "regex" es;
+    e <- assertString e1;
+    s <- assertString e2;
+    return $ mkBoolExpr $ regexExpr e s;
+}
+
+-- |
+-- regexExpr creates a regex expression that returns true if the first expression matches the second string. 
+regexExpr :: Expr Text -> Expr Text -> Expr Bool
+regexExpr e s = trimBool Expr {
+    desc = mkDesc "regex" [desc e, desc s]
+    , eval = \v -> do {
+        s1 <- eval s v;
+        e1 <- eval e v;
+        return $ (=~) (unpack s1) (unpack e1);
+    }
+}
+
+-- |
+-- mkToLowerExpr dynamically creates a toLower expression.
+mkToLowerExpr :: [AnyExpr] -> Either String AnyExpr
+mkToLowerExpr es = do {
+    e <- assertArgs1 "toLower" es;
+    s <- assertString e;
+    return $ mkStringExpr $ toLowerExpr s;
+}
+
+-- |
+-- toLowerExpr creates a toLower expression that converts the input string to a lowercase string.
+toLowerExpr :: Expr Text -> Expr Text
+toLowerExpr e = trimString Expr {
+    desc = mkDesc "toLower" [desc e]
+    , eval = \v -> toLower <$> eval e v
+}
+
+-- |
+-- mkToUpperExpr dynamically creates a toUpper expression.
+mkToUpperExpr :: [AnyExpr] -> Either String AnyExpr
+mkToUpperExpr es = do {
+    e <- assertArgs1 "toUpper" es;
+    s <- assertString e;
+    return $ mkStringExpr $ toUpperExpr s;
+}
+
+-- |
+-- toUpperExpr creates a toUpper expression that converts the input string to an uppercase string.
+toUpperExpr :: Expr Text -> Expr Text
+toUpperExpr e = trimString Expr {
+    desc = mkDesc "toUpper" [desc e]
+    , eval = \v -> toUpper <$> eval e v
+}
diff --git a/src/Data/Katydid/Relapse/Exprs/Type.hs b/src/Data/Katydid/Relapse/Exprs/Type.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Exprs/Type.hs
@@ -0,0 +1,36 @@
+-- |
+-- This module contains the Relapse type expression.
+
+module Data.Katydid.Relapse.Exprs.Type (
+    mkTypeExpr
+    , typeExpr
+) where
+
+import Data.Katydid.Relapse.Expr
+
+-- |
+-- mkTypeExpr is used by the parser to create a type expression for the specific input type.
+mkTypeExpr :: [AnyExpr] -> Either String AnyExpr
+mkTypeExpr es = do {
+    e <- assertArgs1 "type" es; 
+    case e of
+    (AnyExpr _ (BoolFunc _)) -> mkBoolExpr . typeExpr <$> assertBool e;
+    (AnyExpr _ (IntFunc _)) -> mkBoolExpr . typeExpr <$> assertInt e;
+    (AnyExpr _ (UintFunc _)) -> mkBoolExpr . typeExpr <$> assertUint e;
+    (AnyExpr _ (DoubleFunc _)) -> mkBoolExpr . typeExpr <$> assertDouble e;
+    (AnyExpr _ (StringFunc _)) -> mkBoolExpr . typeExpr <$> assertString e;
+    (AnyExpr _ (BytesFunc _)) -> mkBoolExpr . typeExpr <$> assertBytes e;
+}
+
+-- |
+-- typeExpr creates an expression that returns true if the containing expression does not return an error.
+-- For example: `(typeExpr varBoolExpr)` will ony return true is the field value is a bool.
+typeExpr :: Expr a -> Expr Bool
+typeExpr e = Expr {
+    desc = mkDesc "type" [desc e]
+    , eval = \v -> case eval e v of
+        (Left _) -> return False
+        (Right _) -> return True
+}
+
+
diff --git a/src/Data/Katydid/Relapse/Exprs/Var.hs b/src/Data/Katydid/Relapse/Exprs/Var.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Exprs/Var.hs
@@ -0,0 +1,127 @@
+-- |
+-- This module contains all expressions for Relapse variables.
+
+module Data.Katydid.Relapse.Exprs.Var (
+    varBoolExpr
+    , varIntExpr
+    , varUintExpr
+    , varDoubleExpr
+    , varStringExpr
+    , varBytesExpr
+    , isVar
+) where
+
+import Data.Text (Text)
+import Data.ByteString (ByteString)
+
+import qualified Data.Katydid.Parser.Parser as Parser
+
+import Data.Katydid.Relapse.Expr
+
+-- |
+-- isVar returns whether an expression is one of the six variable expressions.
+isVar :: Desc -> Bool
+isVar d = null (_params d) && case _name d of
+    "$bool" -> True
+    "$int" -> True
+    "$uint" -> True
+    "$double" -> True
+    "$string" -> True
+    "$[]byte" -> True
+    _ -> False
+
+-- |
+-- varBoolExpr creates a bool variable expression.
+varBoolExpr :: Expr Bool
+varBoolExpr = Expr {
+    desc = Desc {
+        _name = "$bool"
+        , _toStr = "$bool"
+        , _hash = hashWithName "$bool" []
+        , _params = []
+        , _hasVar = True
+    }
+    , eval = \l -> case l of
+        (Parser.Bool b) -> Right b
+        _ -> Left "not a bool"
+}
+
+-- |
+-- varIntExpr creates an int variable expression.
+varIntExpr :: Expr Int
+varIntExpr = Expr {
+    desc = Desc {
+        _name = "$int"
+        , _toStr = "$int"
+        , _hash = hashWithName "$int" []
+        , _params = []
+        , _hasVar = True
+    }
+    , eval = \l -> case l of
+        (Parser.Int i) -> Right i
+        _ -> Left "not an int"
+}
+
+-- |
+-- varUintExpr creates a uint variable expression.
+varUintExpr :: Expr Word
+varUintExpr = Expr {
+    desc = Desc {
+        _name = "$uint"
+        , _toStr = "$uint"
+        , _hash = hashWithName "$uint" []
+        , _params = []
+        , _hasVar = True
+    }
+    , eval = \l -> case l of
+        (Parser.Uint u) -> Right u
+        _ -> Left "not a uint"
+}
+
+-- |
+-- varDoubleExpr creates a double variable expression.
+varDoubleExpr :: Expr Double
+varDoubleExpr = Expr {
+    desc = Desc {
+        _name = "$double"
+        , _toStr = "$double"
+        , _hash = hashWithName "$double" []
+        , _params = []
+        , _hasVar = True
+    }
+    , eval = \l -> case l of
+        (Parser.Double d) -> Right d
+        _ -> Left "not a double"
+}
+
+-- |
+-- varStringExpr creates a string variable expression.
+varStringExpr :: Expr Text
+varStringExpr = Expr {
+    desc = Desc {
+        _name = "$string"
+        , _toStr = "$string"
+        , _hash = hashWithName "$string" []
+        , _params = []
+        , _hasVar = True
+    }
+    , eval = \l -> case l of
+        (Parser.String s) -> Right s
+        _ -> Left "not a string"
+}
+
+-- |
+-- varBytesExpr creates a bytes variable expression.
+varBytesExpr :: Expr ByteString
+varBytesExpr = Expr {
+    desc = Desc {
+        _name = "$[]byte"
+        , _toStr = "$[]byte"
+        , _hash = hashWithName "$[]byte" []
+        , _params = []
+        , _hasVar = True
+    }
+    , eval = \l -> case l of
+        (Parser.Bytes b) -> Right b
+        _ -> Left "not bytes"
+}
diff --git a/src/Data/Katydid/Relapse/IfExprs.hs b/src/Data/Katydid/Relapse/IfExprs.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/IfExprs.hs
@@ -0,0 +1,86 @@
+-- |
+-- This is an internal relapse module.
+--
+-- It contains multiple implementations of if expressions.
+
+module Data.Katydid.Relapse.IfExprs (
+    IfExprs, IfExpr, newIfExpr,
+    evalIfExprs, compileIfExprs,
+    ZippedIfExprs, zipIfExprs, evalZippedIfExprs
+) where
+
+import Data.Katydid.Parser.Parser
+
+import Data.Katydid.Relapse.Smart
+import Data.Katydid.Relapse.Expr
+import Data.Katydid.Relapse.Exprs.Logic
+import Data.Katydid.Relapse.Simplify
+import Data.Katydid.Relapse.Zip
+
+-- |
+-- IfExpr contains a condition and a return pattern for each of the two cases.
+newtype IfExpr = IfExpr (Expr Bool, Pattern, Pattern)
+
+-- |
+-- newIfExpr creates an IfExpr.
+newIfExpr :: Expr Bool -> Pattern -> Pattern -> IfExpr
+newIfExpr c t e = IfExpr (c, t, e)
+
+-- | IfExprs is a tree of if expressions, which contains a list of resulting patterns on each of its leaves.
+data IfExprs
+    = Cond {
+        cond :: Expr Bool
+        , thn :: IfExprs
+        , els :: IfExprs
+    }
+    | Ret [Pattern]
+
+-- | compileIfExprs compiles a list of if expressions in an IfExprs tree, for efficient evaluation.
+compileIfExprs :: [IfExpr] -> IfExprs
+compileIfExprs [] = Ret []
+compileIfExprs (IfExpr ifExpr:es) = addIfExpr ifExpr (compileIfExprs es)
+
+-- | valIfExprs evaluates a tree of if expressions and returns the resulting patterns or an error.
+evalIfExprs :: IfExprs -> Label -> Either String [Pattern]
+evalIfExprs (Ret ps) _ = return ps
+evalIfExprs (Cond c t e) l = do {
+    b <- eval c l;
+    if b then evalIfExprs t l else evalIfExprs e l
+}
+
+addIfExpr :: (Expr Bool, Pattern, Pattern) -> IfExprs -> IfExprs
+addIfExpr (c, t, e) (Ret ps) =
+    Cond c (Ret (t:ps)) (Ret (e:ps))
+addIfExpr (c, t, e) (Cond cs ts es)
+    | c == cs = Cond cs (addRet t ts) (addRet e es)
+    | boolExpr False == andExpr c cs = Cond cs (addRet e ts) (addIfExpr (c, t, e) es)
+    | boolExpr False == andExpr (notExpr c) cs = Cond cs (addIfExpr (c, t, e) ts) (addRet t es)
+    | otherwise = Cond cs (addIfExpr (c, t, e) ts) (addIfExpr (c, t, e) es)
+
+addRet :: Pattern -> IfExprs -> IfExprs
+addRet p (Ret ps) = Ret (p:ps)
+addRet p (Cond c t e) = Cond c (addRet p t) (addRet p e)
+
+-- |
+-- ZippedIfExprs is a tree of if expressions, but with a zipped pattern list and a zipper on each of the leaves.
+data ZippedIfExprs
+    = ZippedCond {
+        zcond :: Expr Bool
+        , zthn :: ZippedIfExprs
+        , zels :: ZippedIfExprs
+    }
+    | ZippedRet [Pattern] Zipper
+
+-- | zipIfExprs compresses an if expression tree's leaves.
+zipIfExprs :: IfExprs -> ZippedIfExprs
+zipIfExprs (Cond c t e) = ZippedCond c (zipIfExprs t) (zipIfExprs e)
+zipIfExprs (Ret ps) = let (zps, zs) = zippy ps in ZippedRet zps zs
+
+-- | evalZippedIfExprs evaulates a ZippedIfExprs tree and returns the zipped pattern list and zipper from the resulting leaf.
+evalZippedIfExprs :: ZippedIfExprs -> Label -> Either String ([Pattern], Zipper)
+evalZippedIfExprs (ZippedRet ps zs) _ = return (ps, zs)
+evalZippedIfExprs (ZippedCond c t e) v = do {
+    b <- eval c v;
+    if b then evalZippedIfExprs t v else evalZippedIfExprs e v
+}
+
diff --git a/src/Data/Katydid/Relapse/MemDerive.hs b/src/Data/Katydid/Relapse/MemDerive.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/MemDerive.hs
@@ -0,0 +1,91 @@
+-- |
+-- This module is an efficient implementation of the derivative algorithm for trees.
+--
+-- It is intended to be used for production purposes.
+--
+-- This means that it gives up some readability for speed.
+--
+-- This module provides memoization of the nullable, calls and returns functions.
+
+module Data.Katydid.Relapse.MemDerive (
+    derive, Mem, newMem, validate
+) where
+
+import qualified Data.Map.Strict as M
+import Control.Monad.State (State, runState, lift, state)
+import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
+
+import Data.Katydid.Parser.Parser
+
+import qualified Data.Katydid.Relapse.Derive as Derive
+import Data.Katydid.Relapse.Smart (Grammar, Pattern, lookupRef, nullable, lookupMain)
+import Data.Katydid.Relapse.IfExprs
+import Data.Katydid.Relapse.Expr
+import Data.Katydid.Relapse.Zip
+
+mem :: Ord k => (k -> v) -> k -> M.Map k v -> (v, M.Map k v)
+mem f k m
+    | M.member k m = (m M.! k, m)
+    | otherwise = let res = f k
+        in (res, M.insert k res m)
+
+type Calls = M.Map [Pattern] IfExprs
+type Returns = M.Map ([Pattern], [Bool]) [Pattern]
+
+-- |
+-- Mem is the object used to store memoized results of the nullable, calls and returns functions.
+newtype Mem = Mem (Calls, Returns)
+
+-- |
+-- newMem creates a object used for memoization by the validate function.
+-- Each grammar should create its own memoize object.
+newMem :: Mem
+newMem = Mem (M.empty, M.empty)
+
+calls :: Grammar -> [Pattern] -> State Mem IfExprs
+calls g k = state $ \(Mem (c, r)) -> let (v', c') = mem (Derive.calls g) k c;
+    in (v', Mem (c', r))
+
+returns :: Grammar -> ([Pattern], [Bool]) -> State Mem [Pattern]
+returns g k = state $ \(Mem (c, r)) -> let (v', r') = mem (Derive.returns g) k r;
+    in (v', Mem (c, r'))
+
+mderive :: Tree t => Grammar -> [Pattern] -> [t] -> ExceptT String (State Mem) [Pattern]
+mderive _ ps [] = return ps
+mderive g ps (tree:ts) = do {
+    ifs <- lift $ calls g ps;
+    childps <- hoistExcept $ evalIfExprs ifs (getLabel tree);
+    (zchildps, zipper) <- return $ zippy childps;
+    childres <- mderive g zchildps (getChildren tree);
+    let 
+        nulls = map nullable childres
+        unzipns = unzipby zipper nulls
+    ;
+    rs <- lift $ returns g (ps, unzipns);
+    mderive g rs ts
+}
+
+hoistExcept :: (Monad m) => Either e a -> ExceptT e m a
+hoistExcept = ExceptT . return
+
+-- |
+-- derive is the classic derivative implementation for trees.
+derive :: Tree t => Grammar -> [t] -> Either String Pattern
+derive g ts =
+    let start = [lookupMain g]
+        (res, _) = runState (runExceptT $ mderive g start ts) newMem
+    in case res of
+        (Left l) -> Left l
+        (Right [r]) -> return r
+        (Right rs) -> Left $ "not a single pattern: " ++ show rs
+
+-- |
+-- validate is the uses the derivative implementation for trees and
+-- return whether tree is valid, given the input grammar and start pattern.
+validate :: Tree t => Grammar -> Pattern -> [t] -> (State Mem) Bool
+validate g start tree = do {
+    rs <- runExceptT (mderive g [start] tree);
+    return $ case rs of
+        (Right [r]) -> nullable r
+        _ -> False
+}
diff --git a/src/Data/Katydid/Relapse/Parser.hs b/src/Data/Katydid/Relapse/Parser.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Parser.hs
@@ -0,0 +1,388 @@
+-- |
+-- This module parses the Relapse Grammar using the Parsec Library.
+
+module Data.Katydid.Relapse.Parser (
+    -- * Parse Grammar
+    parseGrammar, parseGrammarWithUDFs
+    -- * Internal functions
+    -- | These functions are exposed for testing purposes.
+    , grammar, pattern, nameExpr, expr, 
+    idLit, bytesCastLit, stringLit, doubleCastLit, uintCastLit, intLit, ws
+) where
+
+import Text.ParserCombinators.Parsec
+import Numeric (readDec, readOct, readHex, readFloat)
+import Data.Char (chr)
+import qualified Data.Text as Text
+import qualified Data.ByteString.Char8 as ByteString
+import Control.Arrow (left)
+
+import Data.Katydid.Relapse.Expr
+import Data.Katydid.Relapse.Exprs
+import Data.Katydid.Relapse.Exprs.Logic
+import Data.Katydid.Relapse.Exprs.Var
+import Data.Katydid.Relapse.Ast
+
+-- | parseGrammar parses the Relapse Grammar.
+parseGrammar :: String -> Either String Grammar
+parseGrammar = parseGrammarWithUDFs stdOnly
+
+-- | parseGrammarWithUDFs parses the Relapse Grammar with extra user defined functions.
+parseGrammarWithUDFs :: MkFunc -> String -> Either String Grammar
+parseGrammarWithUDFs extraUDFs str = 
+    let mkFunc n es = case mkExpr n es of
+            (Left _) -> extraUDFs n es
+            (Right v) -> return v
+    in left show $ parse (grammar mkFunc <* eof) "" str
+
+infixl 4 <++>
+(<++>) :: CharParser () String -> CharParser () String -> CharParser () String
+f <++> g = (++) <$> f <*> g
+
+infixr 5 <::>
+(<::>) :: CharParser () Char -> CharParser () String -> CharParser () String
+f <::> g = (:) <$> f <*> g
+
+check :: Either String a -> CharParser () a
+check e = case e of
+    (Left err) -> fail err
+    (Right v) -> return v
+
+empty :: CharParser () String
+empty = return ""
+
+opt :: CharParser () Char -> CharParser () String
+opt p = (:"") <$> p <|> empty
+
+_lineComment :: CharParser () ()
+_lineComment = char '/' *> many (noneOf "\n") <* char '\n' *> return ()
+
+_blockComment :: CharParser () ()
+_blockComment = char '*' *> many (noneOf "*") <* char '*' <* char '/' *> return ()
+
+_comment :: CharParser () ()
+_comment = char '/' *> (_lineComment <|> _blockComment)
+
+_ws :: CharParser () ()
+_ws = _comment <|> () <$ space
+
+-- | For internal testing
+ws :: CharParser () ()
+ws = () <$ many _ws
+
+bool :: CharParser () Bool
+bool = True <$ string "true"
+    <|> False <$ string "false"
+
+_decimalLit :: CharParser () Int
+_decimalLit = oneOf "123456789" <::> many digit >>= _read readDec
+
+_octalLit :: CharParser () Int
+_octalLit = many1 octDigit >>= _read readOct
+
+_hexLit :: CharParser () Int
+_hexLit = many1 hexDigit >>= _read readHex
+
+_read :: ReadS a -> String -> CharParser () a
+_read read s = case read s of
+    [(n, "")]   -> return n
+    ((n, ""):_) -> return n
+    _           -> fail "digit"
+
+_optionalSign :: (Num a) => CharParser () a
+_optionalSign = -1 <$ char '-' <|> return 1
+
+_signedIntLit :: CharParser () Int
+_signedIntLit = (*) <$> _optionalSign <*> _intLit
+
+_intLit :: CharParser () Int
+_intLit = _decimalLit 
+    <|> char '0' *> (_octalLit 
+                    <|> (oneOf "xX" *> _hexLit)
+                    <|> return 0
+    )
+
+-- | For internal testing
+intLit :: CharParser () Int
+intLit = string "int(" *> _signedIntLit <* char ')'
+    <|> _signedIntLit
+    <?> "int_lit"
+
+uintLit :: CharParser () Word
+uintLit = do {
+    i <- intLit;
+    if i < 0
+        then fail "negative uint" 
+        else return $ fromIntegral i;
+}
+
+-- | For internal testing
+uintCastLit :: CharParser () Word
+uintCastLit = string "uint(" *> uintLit <* char ')'
+
+_exponent :: CharParser () String
+_exponent = oneOf "eE" <::> (
+    oneOf "+-" <::> many1 digit 
+    <|> many1 digit)
+
+_floatLit :: CharParser () Double
+_floatLit = do
+    i <- many1 digit
+    e <- _exponent 
+        <|> ((string "." <|> empty) <++> 
+            (_exponent 
+            <|> many1 digit <++>
+                (_exponent
+                <|> empty)
+            )
+        ) 
+        <|> empty
+    _read readFloat (i ++ e)
+
+-- | For internal testing
+doubleCastLit :: CharParser () Double
+doubleCastLit = string "double(" *> ((*) <$> _optionalSign <*> _floatLit) <* char ')'
+
+-- | For internal testing
+idLit :: CharParser () String
+idLit = (letter <|> char '_') <::> many (alphaNum <|> char '_')
+
+_qualid :: CharParser () String
+_qualid = idLit <++> (concat <$> many (char '.' <::> idLit))
+
+_bigUValue :: CharParser () Char
+_bigUValue = char 'U' *> do {
+    hs <- count 8 hexDigit;
+    n <- _read readHex hs;
+    return $ toEnum n
+}
+
+_littleUValue :: CharParser () Char
+_littleUValue = char 'u' *> do { 
+    hs <- count 4 hexDigit;
+    n <- _read readHex hs;
+    return $ toEnum n
+}
+
+_escapedChar :: CharParser () Char
+_escapedChar = choice (zipWith (\c r -> r <$ char c) "abnfrtv'\\\"/" "\a\b\n\f\r\t\v\'\\\"/")
+
+_unicodeValue :: CharParser () Char
+_unicodeValue = (char '\\' *> 
+    (_bigUValue 
+        <|> _littleUValue 
+        <|> _hexByteUValue 
+        <|> _escapedChar
+        <|> _octalByteUValue)
+    ) <|> noneOf "\\\""
+
+_interpretedString :: CharParser () String
+_interpretedString = between (char '"') (char '"') (many _unicodeValue)
+
+_rawString :: CharParser () String
+_rawString = between (char '`') (char '`') (many $ noneOf "`")
+
+-- | For internal testing
+stringLit :: CharParser () Text.Text
+stringLit = Text.pack <$> (_rawString <|> _interpretedString)
+
+_hexByteUValue :: CharParser () Char
+_hexByteUValue = char 'x' *> do {
+    hs <- count 2 hexDigit;
+    n <- _read readHex hs;
+    return $ chr n
+}
+
+_octalByteUValue :: CharParser () Char
+_octalByteUValue = do {
+    os <- count 3 octDigit;
+    n <- _read readOct os;
+    return $ toEnum n
+}
+
+_byteLit :: CharParser () Char
+_byteLit = do {
+    i <- _intLit;
+    if i > 255 then
+        fail $ "too large for byte: " ++ show i
+    else
+        return $ chr i
+}
+
+_byteElem :: CharParser () Char
+_byteElem = _byteLit <|> between (char '\'') (char '\'') (_unicodeValue <|> _octalByteUValue <|> _hexByteUValue)
+
+-- | For internal testing
+bytesCastLit :: CharParser () ByteString.ByteString
+bytesCastLit = ByteString.pack <$> (string "[]byte{" *> sepBy (ws *> _byteElem <* ws) (char ',') <* char '}')
+
+_literal :: CharParser () AnyExpr
+_literal = mkBoolExpr . boolExpr <$> bool
+    <|> mkIntExpr . intExpr <$> intLit
+    <|> mkUintExpr . uintExpr <$> uintCastLit
+    <|> mkDoubleExpr . doubleExpr <$> doubleCastLit
+    <|> mkStringExpr . stringExpr <$> stringLit
+    <|> mkBytesExpr . bytesExpr <$> bytesCastLit
+
+_terminal :: CharParser () AnyExpr
+_terminal = (char '$' *> (
+    mkBoolExpr varBoolExpr <$ string "bool"
+    <|> mkIntExpr varIntExpr <$ string "int"
+    <|> mkUintExpr varUintExpr <$ string "uint"
+    <|> mkDoubleExpr varDoubleExpr <$ string "double"
+    <|> mkStringExpr varStringExpr <$ string "string"
+    <|> mkBytesExpr varBytesExpr <$ string "[]byte" ))
+    <|> _literal
+
+_builtinSymbol :: CharParser () String
+_builtinSymbol = string "==" 
+    <|> string "!=" 
+    <|> char '<' <::> opt (char '=')
+    <|> char '>' <::> opt (char '=')
+    <|> string "~="
+    <|> string "*="
+    <|> string "^="
+    <|> string "$="
+    <|> string "::"
+
+_builtin :: MkFunc -> CharParser () AnyExpr
+_builtin mkFunc = mkBuiltIn <$> _builtinSymbol <*> (ws *> _expr mkFunc) >>= check
+
+_function :: MkFunc -> CharParser () AnyExpr
+_function mkFunc = mkFunc <$> idLit <*> (char '(' *> sepBy (ws *> _expr mkFunc <* ws) (char ',') <* char ')') >>= check
+
+_listType :: CharParser () String
+_listType = char '[' <::> char ']' <::> (
+    string "bool"
+    <|> string "int"
+    <|> string "uint"
+    <|> string "double"
+    <|> string "string"
+    <|> string "[]byte" )
+
+_mustBool :: AnyExpr -> CharParser () (Expr Bool)
+_mustBool = check . assertBool
+
+newList :: String -> [AnyExpr] -> CharParser () AnyExpr
+newList "[]bool" es = mkBoolsExpr . boolsExpr <$> mapM (check . assertBool) es
+newList "[]int" es = mkIntsExpr . intsExpr <$> mapM (check . assertInt) es
+newList "[]uint" es = mkUintsExpr . uintsExpr <$> mapM (check . assertUint) es
+newList "[]double" es = mkDoublesExpr . doublesExpr <$> mapM (check . assertDouble) es
+newList "[]string" es = mkStringsExpr . stringsExpr <$> mapM (check . assertString) es
+newList "[][]byte" es = mkListOfBytesExpr . listOfBytesExpr <$> mapM (check . assertBytes) es
+
+_list :: MkFunc -> CharParser () AnyExpr
+_list mkFunc = do {
+    ltype <- _listType;
+    es <- ws *> char '{' *> sepBy (ws *> _expr mkFunc <* ws) (char ',') <* char '}';
+    newList ltype es
+}
+
+_expr :: MkFunc -> CharParser () AnyExpr
+_expr mkFunc = try _terminal <|> _list mkFunc <|> _function mkFunc
+
+-- | For internal testing
+expr :: MkFunc -> CharParser () (Expr Bool)
+expr mkFunc = (try _terminal <|> _builtin mkFunc <|> _function mkFunc) >>= _mustBool
+
+_nameString :: CharParser () (Expr Bool)
+_nameString = (mkBuiltIn "==" <$> 
+    (_literal <|> 
+    (mkStringExpr . stringExpr . Text.pack <$> idLit))) 
+    >>= check >>= _mustBool
+
+sepBy2 :: CharParser () a -> String -> CharParser () [a]
+sepBy2 p sep = do {
+    x1 <- p;
+    string sep;
+    x2 <- p;
+    xs <- many (try (string sep *> p));
+    return (x1:x2:xs)
+}
+
+_nameChoice :: CharParser () (Expr Bool)
+_nameChoice = foldl1 orExpr <$> sepBy2 (ws *> nameExpr <* ws) "|"
+
+-- | For internal testing
+nameExpr :: CharParser () (Expr Bool)
+nameExpr =  (boolExpr True <$ char '_')
+    <|> (notExpr <$> (char '!' *> ws *> char '(' *> ws *> nameExpr <* ws <* char ')'))
+    <|> (char '(' *> ws *> _nameChoice <* ws <* char ')')
+    <|> _nameString
+
+_concatPattern :: MkFunc -> CharParser () Pattern
+_concatPattern mkFunc = char '[' *> (foldl1 Concat <$> sepBy2 (ws *> pattern mkFunc <* ws) ",") <* optional (char ',' <* ws) <* char ']'
+
+_interleavePattern :: MkFunc -> CharParser () Pattern
+_interleavePattern mkFunc = char '{' *> (foldl1 Interleave <$> sepBy2 (ws *> pattern mkFunc <* ws) ";") <* optional (char ';' <* ws) <* char '}'
+
+_parenPattern :: MkFunc -> CharParser () Pattern
+_parenPattern mkFunc = do {
+    char '(';
+    ws;
+    first <- pattern mkFunc;
+    ws;
+    ( char ')' *> ws *>
+        (
+            ZeroOrMore first <$ char '*'
+            <|> Optional first <$ char '?'
+        )
+    ) <|> ( 
+        (
+            (first <$ char '|' >>= _orList mkFunc) <|> 
+            (first <$ char '&' >>= _andList mkFunc)
+        ) <* char ')'
+    )
+}
+
+_orList :: MkFunc -> Pattern -> CharParser () Pattern
+_orList mkFunc p = Or p . foldl1 Or <$> sepBy1 (ws *> pattern mkFunc <* ws) (char '|')
+
+_andList :: MkFunc -> Pattern -> CharParser () Pattern
+_andList mkFunc p = And p . foldl1 And <$> sepBy1 (ws *> pattern mkFunc <* ws) (char '&')
+
+_refPattern :: CharParser () Pattern
+_refPattern = Reference <$> (char '@' *> ws *> idLit)
+
+_notPattern :: MkFunc -> CharParser () Pattern
+_notPattern mkFunc = Not <$> (char '!' *> ws *> char '(' *> ws *> pattern mkFunc <* ws <* char ')')
+
+_emptyPattern :: CharParser () Pattern
+_emptyPattern = Empty <$ string "<empty>"
+
+_zanyPattern :: CharParser () Pattern
+_zanyPattern = ZAny <$ string "*"
+
+_containsPattern :: MkFunc -> CharParser () Pattern
+_containsPattern mkFunc = Contains <$> (char '.' *> pattern mkFunc)
+
+_treenodePattern :: MkFunc -> CharParser () Pattern
+_treenodePattern mkFunc = Node <$> nameExpr <*> ( ws *> ( try (char ':' *> ws *> pattern mkFunc) <|> _depthPattern mkFunc) )
+
+_depthPattern :: MkFunc -> CharParser () Pattern
+_depthPattern mkFunc = _concatPattern mkFunc <|> _interleavePattern mkFunc<|> _containsPattern mkFunc
+    <|> flip Node Empty <$> ( (string "->" *> expr mkFunc) <|> (_builtin mkFunc>>= _mustBool) )
+
+newContains :: CharParser () AnyExpr -> CharParser () Pattern
+newContains e = flip Node Empty <$> ((mkBuiltIn "*=" <$> e) >>= check >>= _mustBool)
+
+-- | For internal testing
+pattern :: MkFunc -> CharParser () Pattern
+pattern mkFunc = char '*' *> (
+        (char '=' *> newContains (ws *> _expr mkFunc))
+        <|> return ZAny
+    ) <|> _parenPattern mkFunc
+    <|> _refPattern
+    <|> try _emptyPattern
+    <|> try (_treenodePattern mkFunc)
+    <|> try (_depthPattern mkFunc)
+    <|> _notPattern mkFunc
+    
+_patternDecl :: MkFunc -> CharParser () Grammar
+_patternDecl mkFunc = newRef <$> (char '#' *> ws *> idLit) <*> (ws *> char '=' *> ws *> pattern mkFunc)
+
+-- | For internal testing
+grammar :: MkFunc -> CharParser () Grammar
+grammar mkFunc = ws *> (foldl1 union <$> many1 (_patternDecl mkFunc <* ws))
+    <|> union <$> (newRef "main" <$> pattern mkFunc) <*> (foldl union emptyRef <$> many (ws *> _patternDecl mkFunc <* ws))
+
diff --git a/src/Data/Katydid/Relapse/Relapse.hs b/src/Data/Katydid/Relapse/Relapse.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Relapse.hs
@@ -0,0 +1,67 @@
+-- |
+-- This module provides an implementation of the relapse validation language.
+--
+-- Relapse is intended to be used for validation of trees or filtering of lists of trees.
+--
+-- Katydid currently provides two types of trees out of the box: Json and XML, 
+-- but relapse supports any type of tree as long the type 
+-- is of the Tree typeclass provided by the Parsers module.
+--
+-- The validate and filter functions expects a Tree to be a list of trees, 
+-- since not all serialization formats have a single root.
+-- For example, valid json like "[1, 2]" does not have a single root.
+-- Relapse can also validate these types of trees.  
+-- If your tree has a single root, simply provide a singleton list as input.
+
+module Data.Katydid.Relapse.Relapse (
+    parse, parseWithUDFs, Grammar
+    , validate, filter
+) where
+
+import Prelude hiding (filter)
+import Control.Monad.State (runState)
+import Control.Monad (filterM)
+
+import Data.Katydid.Parser.Parser
+
+import qualified Data.Katydid.Relapse.Parser as Parser
+import qualified Data.Katydid.Relapse.Ast as Ast
+import qualified Data.Katydid.Relapse.MemDerive as MemDerive
+import qualified Data.Katydid.Relapse.Smart as Smart
+import qualified Data.Katydid.Relapse.Exprs as Exprs
+
+-- | Grammar represents a compiled relapse grammar.
+newtype Grammar = Grammar Smart.Grammar
+
+-- |
+-- parse parses the relapse grammar and returns either a parsed grammar or an error string.
+parse :: String -> Either String Grammar
+parse grammarString = do {
+    parsed <- Parser.parseGrammar grammarString;
+    Grammar <$> Smart.compile parsed;
+}
+
+-- |
+-- parseWithUDFs parses the relapse grammar with extra user defined functions
+-- and returns either a parsed grammar or an error string.
+parseWithUDFs :: Exprs.MkFunc -> String -> Either String Grammar
+parseWithUDFs userLib grammarString = do {
+    parsed <- Parser.parseGrammarWithUDFs userLib grammarString;
+    Grammar <$> Smart.compile parsed;
+}
+
+-- |
+-- validate returns whether a tree is valid, given the grammar.
+validate :: Tree t => Grammar -> [t] -> Bool
+validate g tree = case filter g [tree] of
+    [] -> False
+    _ -> True
+
+-- |
+-- filter returns a filtered list of trees, given the grammar.
+filter :: Tree t => Grammar -> [[t]] -> [[t]]
+filter (Grammar g) trees = 
+    let start = Smart.lookupMain g
+        f = filterM (MemDerive.validate g start) trees
+        (r, _) = runState f MemDerive.newMem
+    in r
diff --git a/src/Data/Katydid/Relapse/Simplify.hs b/src/Data/Katydid/Relapse/Simplify.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Simplify.hs
@@ -0,0 +1,136 @@
+{-#LANGUAGE GADTs #-}
+
+-- |
+-- This module simplifies Relapse patterns.
+
+module Data.Katydid.Relapse.Simplify (
+    simplify  
+) where
+
+import qualified Data.Set as S
+
+import Data.Katydid.Relapse.Ast
+import Data.Katydid.Relapse.Expr
+import Data.Katydid.Relapse.Exprs.Logic
+
+-- |
+-- simplify simplifies an input pattern to an equivalent simpler pattern.
+simplify :: Grammar -> Pattern -> Pattern
+simplify g pat =
+    let simp = simplify' g
+    in case pat of
+    Empty -> Empty
+    ZAny -> ZAny
+    (Node v p) -> simplifyNode v (simp p)
+    (Concat p1 p2) -> simplifyConcat (simp p1) (simp p2)
+    (Or p1 p2) -> simplifyOr g (simp p1) (simp p2)
+    (And p1 p2) -> simplifyAnd g (simp p1) (simp p2)
+    (ZeroOrMore p) -> simplifyZeroOrMore (simp p)
+    (Not p) -> simplifyNot (simp p)
+    (Optional p) -> simplifyOptional (simp p)
+    (Interleave p1 p2) -> simplifyInterleave (simp p1) (simp p2)
+    (Contains p) -> simplifyContains (simp p)
+    p@(Reference _) -> p
+
+simplify' :: Grammar -> Pattern -> Pattern
+simplify' g p = checkRef g $ simplify g p
+
+simplifyNode :: Expr Bool -> Pattern -> Pattern
+simplifyNode v p = case evalConst v of
+    (Just False) -> Not ZAny
+    _ -> Node v p
+
+simplifyConcat :: Pattern -> Pattern -> Pattern
+simplifyConcat (Not ZAny) _ = Not ZAny
+simplifyConcat _ (Not ZAny) = Not ZAny
+simplifyConcat (Concat p1 p2) p3 = 
+    simplifyConcat p1 (Concat p2 p3)
+simplifyConcat Empty p = p
+simplifyConcat p Empty = p
+simplifyConcat ZAny (Concat p ZAny) = Contains p
+simplifyConcat p1 p2 = Concat p1 p2
+
+simplifyOr :: Grammar -> Pattern -> Pattern -> Pattern
+simplifyOr _ (Not ZAny) p = p
+simplifyOr _ p (Not ZAny) = p
+simplifyOr _ ZAny _ = ZAny
+simplifyOr _ _ ZAny = ZAny
+simplifyOr _ (Node v1 Empty) (Node v2 Empty) = Node (orExpr v1 v2) Empty
+simplifyOr g Empty p 
+    | nullable g p == Right True = p
+    | otherwise = Or Empty p
+simplifyOr g p Empty
+    | nullable g p == Right True = p 
+    | otherwise = Or Empty p
+simplifyOr _ p1 p2 = bin Or $ simplifyChildren Or $ S.toAscList $ setOfOrs p1 `S.union` setOfOrs p2
+
+simplifyChildren :: (Pattern -> Pattern -> Pattern) -> [Pattern] -> [Pattern]
+simplifyChildren _ [] = []
+simplifyChildren _ [p] = [p]
+simplifyChildren op (p1@(Node v1 c1):(p2@(Node v2 c2):ps))
+    | v1 == v2 = simplifyChildren op $ Node v1 (op c1 c2):ps
+    | otherwise = p1:simplifyChildren op (p2:ps)
+simplifyChildren op (p:ps) = p:simplifyChildren op ps
+
+bin :: (Pattern -> Pattern -> Pattern) -> [Pattern] -> Pattern
+bin op [p] = p
+bin op [p1,p2] = op p1 p2
+bin op (p:ps) = op p (bin op ps)
+
+setOfOrs :: Pattern -> S.Set Pattern
+setOfOrs (Or p1 p2) = setOfOrs p1 `S.union` setOfOrs p2
+setOfOrs p = S.singleton p
+
+simplifyAnd :: Grammar -> Pattern -> Pattern -> Pattern
+simplifyAnd _ (Not ZAny) _ = Not ZAny
+simplifyAnd _ _ (Not ZAny) = Not ZAny
+simplifyAnd _ ZAny p = p
+simplifyAnd _ p ZAny = p
+simplifyAnd _ (Node v1 Empty) (Node v2 Empty) = Node (andExpr v1 v2) Empty
+simplifyAnd g Empty p
+    | nullable g p == Right True = Empty
+    | otherwise = Not ZAny
+simplifyAnd g p Empty
+    | nullable g p == Right True = Empty
+    | otherwise = Not ZAny
+simplifyAnd _ p1 p2 = bin And $ simplifyChildren And $ S.toAscList $ setOfAnds p1 `S.union` setOfAnds p2
+
+setOfAnds :: Pattern -> S.Set Pattern
+setOfAnds (And p1 p2) = setOfAnds p1 `S.union` setOfAnds p2
+setOfAnds p = S.singleton p
+
+simplifyZeroOrMore :: Pattern -> Pattern
+simplifyZeroOrMore (ZeroOrMore p) = ZeroOrMore p
+simplifyZeroOrMore p = ZeroOrMore p
+
+simplifyNot :: Pattern -> Pattern
+simplifyNot (Not p) = p
+simplifyNot p = Not p
+
+simplifyOptional :: Pattern -> Pattern
+simplifyOptional Empty = Empty
+simplifyOptional p = Optional p
+
+simplifyInterleave :: Pattern -> Pattern -> Pattern
+simplifyInterleave (Not ZAny) _ = Not ZAny
+simplifyInterleave _ (Not ZAny) = Not ZAny
+simplifyInterleave Empty p = p
+simplifyInterleave p Empty = p
+simplifyInterleave ZAny ZAny = ZAny
+simplifyInterleave p1 p2 = bin Interleave $ S.toAscList $ setOfInterleaves p1 `S.union` setOfInterleaves p2
+
+setOfInterleaves :: Pattern -> S.Set Pattern
+setOfInterleaves (Interleave p1 p2) = setOfInterleaves p1 `S.union` setOfInterleaves p2
+setOfInterleaves p = S.singleton p
+
+simplifyContains :: Pattern -> Pattern
+simplifyContains Empty = ZAny
+simplifyContains ZAny = ZAny
+simplifyContains (Not ZAny) = Not ZAny
+simplifyContains p = Contains p
+
+checkRef :: Grammar -> Pattern -> Pattern
+checkRef g p = case reverseLookupRef p g of
+    Nothing     -> p
+    (Just k)    -> Reference k
+
diff --git a/src/Data/Katydid/Relapse/Smart.hs b/src/Data/Katydid/Relapse/Smart.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Smart.hs
@@ -0,0 +1,417 @@
+-- |
+-- This module describes the smart constructors for Relapse patterns.
+module Data.Katydid.Relapse.Smart (
+    Pattern(..)
+    , Grammar
+    , lookupRef
+    , compile
+    , emptyPat, zanyPat, nodePat
+    , orPat, andPat, notPat 
+    , concatPat, interleavePat
+    , zeroOrMorePat, optionalPat
+    , containsPat, refPat
+    , emptySet
+    , unescapable
+    , nullable
+    , lookupMain
+) where
+
+import qualified Data.Map.Strict as M
+import qualified Data.Set as S
+import Data.List (sort, sortBy, intercalate)
+import Control.Monad (when)
+
+import qualified Data.Katydid.Relapse.Expr as Expr
+import Data.Katydid.Relapse.Exprs.Logic (orExpr, andExpr)
+import qualified Data.Katydid.Relapse.Ast as Ast
+
+-- | compile complies an ast into a smart grammar.
+compile :: Ast.Grammar -> Either String Grammar
+compile g = do {
+    Ast.lookupRef g "main"; -- making sure that the main reference exists.
+    hasRec <- Ast.hasRecursion g;
+    when hasRec $ Left "recursion without interleaved treenode not supported";
+    refs <- M.fromList <$> mapM (\name -> do {
+        p <- Ast.lookupRef g name;
+        return (name, p)
+    }) (Ast.listRefs g);
+    nullRefs <- mapM (Ast.nullable g) refs;
+    Grammar <$> mapM (smart nullRefs) refs
+}
+
+smart :: M.Map String Bool -> Ast.Pattern -> Either String Pattern
+smart _ Ast.Empty = return emptyPat
+smart nulls (Ast.Node e p) = nodePat e <$> smart nulls p
+smart nulls (Ast.Concat a b) = concatPat <$> smart nulls a <*> smart nulls b
+smart nulls (Ast.Or a b) = orPat <$> smart nulls a <*> smart nulls b
+smart nulls (Ast.And a b) = andPat <$> smart nulls a <*> smart nulls b
+smart nulls (Ast.ZeroOrMore p) = zeroOrMorePat <$> smart nulls p
+smart nulls (Ast.Reference name) = refPat nulls name
+smart nulls (Ast.Not p) = notPat <$> smart nulls p
+smart _ Ast.ZAny = return zanyPat
+smart nulls (Ast.Contains p) = containsPat <$> smart nulls p
+smart nulls (Ast.Optional p) = optionalPat <$> smart nulls p
+smart nulls (Ast.Interleave a b) = interleavePat <$> smart nulls a <*> smart nulls b
+
+-- |
+-- Pattern recursively describes a Relapse Pattern.
+data Pattern = Empty
+    | Node {
+        expr :: Expr.Expr Bool
+        , pat :: Pattern
+        , _hash :: Int
+    }
+    | Concat {
+        left :: Pattern
+        , right :: Pattern
+        , _nullable :: Bool
+        , _hash :: Int
+    }
+    | Or {
+        pats :: [Pattern]
+        , _nullable :: Bool
+        , _hash :: Int
+    }
+    | And {
+        pats :: [Pattern]
+        , _nullable :: Bool
+        , _hash :: Int
+    }
+    | ZeroOrMore {
+        pat :: Pattern
+        , _hash :: Int
+    }
+    | Reference {
+        refName :: ValidRef
+        , _nullable :: Bool
+        , _hash :: Int
+    }
+    | Not {
+        pat :: Pattern
+        , _nullable :: Bool
+        , _hash :: Int
+    }
+    | ZAny
+    | Contains {
+        pat :: Pattern
+        , _nullable :: Bool
+        , _hash :: Int
+    }
+    | Optional {
+        pat :: Pattern
+        , _hash :: Int
+    }
+    | Interleave {
+        pats :: [Pattern]
+        , _nullable :: Bool
+        , _hash :: Int
+    }
+    deriving (Eq, Ord)
+
+instance Show Pattern where
+    show = toStr
+
+toStr :: Pattern -> String
+toStr Empty = "<empty>"
+toStr Node{expr=e, pat=p} = show e ++ ":" ++ show p
+toStr Concat{left=l,right=r} = "[" ++ show l ++ "," ++ show r ++ "]"
+toStr Or{pats=ps} = "(" ++ intercalate "|" (map show ps) ++ ")"
+toStr And{pats=ps} = "(" ++ intercalate "&" (map show ps) ++ ")"
+toStr ZeroOrMore{pat=p} = "(" ++ show p ++ ")*"
+toStr Reference{refName=(ValidRef n)} = "@"++n
+toStr Not{pat=p} = "!(" ++ show p ++ ")"
+toStr ZAny = "*"
+toStr Contains{pat=p} = "." ++ show p
+toStr Optional{pat=p} = "(" ++ show p ++ ")?"
+toStr Interleave{pats=ps} = "{" ++ intercalate ";" (map show ps) ++ "}"
+
+-- cmp is an efficient comparison function for patterns.
+-- It is very important that cmp is efficient, 
+-- because it is a bottleneck for simplification and smart construction of large queries.
+cmp :: Pattern -> Pattern -> Ordering
+cmp a b = if hashcmp == EQ then compare a b else hashcmp
+    where hashcmp = compare (hash a) (hash b)
+
+-- eq is an efficient comparison function for patterns.
+-- It is very important that eq is efficient, 
+-- because it is a bottleneck for simplification and smart construction of large queries.
+eq :: Pattern -> Pattern -> Bool
+eq a b = cmp a b == EQ
+
+hash :: Pattern -> Int
+hash Empty = 3
+hash Node{_hash=h} = h
+hash Concat{_hash=h} = h
+hash Or{_hash=h} = h
+hash And{_hash=h} = h
+hash ZeroOrMore{_hash=h} = h
+hash Reference{_hash=h} = h
+hash Not{_hash=h} = h
+hash ZAny = 5
+hash Contains{_hash=h} = h
+hash Optional{_hash=h} = h
+hash Interleave{_hash=h} = h
+
+-- | nullable returns whether the pattern matches the empty string.
+nullable :: Pattern -> Bool
+nullable Empty = True
+nullable Node{} = False
+nullable Concat{_nullable=n} = n
+nullable Or{_nullable=n} = n
+nullable And{_nullable=n} = n
+nullable ZeroOrMore{} = True
+nullable Reference{_nullable=n} = n
+nullable Not{_nullable=n} = n
+nullable ZAny = True
+nullable Contains{_nullable=n} = n
+nullable Optional{} = True
+nullable Interleave{_nullable=n} = n
+
+-- | emptyPat is the smart constructor for the empty pattern.
+emptyPat :: Pattern
+emptyPat = Empty
+
+-- | zanyPat is the smart constructor for the zany pattern.
+zanyPat :: Pattern
+zanyPat = ZAny
+
+-- | notPat is the smart constructor for the not pattern.
+notPat :: Pattern -> Pattern
+notPat Not {pat=p} = p
+notPat p = Not {
+    pat = p
+    , _nullable = not $ nullable p
+    , _hash = 31 * 7 + hash p
+}
+
+-- | emptySet is the smart constructor for the !(*) pattern.
+emptySet :: Pattern
+emptySet = notPat zanyPat
+
+-- | nodePat is the smart constructor for the node pattern.
+nodePat :: Expr.Expr Bool -> Pattern -> Pattern
+nodePat e p =
+    case Expr.evalConst e of
+    (Just False) -> emptySet
+    _ -> Node {
+        expr = e
+        , pat = p
+        , _hash = 31 * (11 + 31 * Expr._hash (Expr.desc e)) + hash p
+    }
+
+isLeaf :: Pattern -> Bool
+isLeaf Node{pat=Empty} = True
+isLeaf _ = False
+
+-- | concatPat is the smart constructor for the concat pattern.
+concatPat :: Pattern -> Pattern -> Pattern
+concatPat notZAny@Not{pat=ZAny} _ = notZAny
+concatPat _ notZAny@Not{pat=ZAny} = notZAny
+concatPat Empty b = b
+concatPat a Empty = a
+concatPat Concat{left=a1, right=a2} b = concatPat a1 (concatPat a2 b)
+concatPat ZAny Concat{left=b1, right=ZAny} = containsPat b1
+concatPat a b = Concat {
+    left = a
+    , right = b 
+    , _nullable = nullable a && nullable b
+    , _hash = 31 * (13 + 31 * hash a) + hash b
+}
+
+-- | containsPat is the smart constructor for the contains pattern.
+containsPat :: Pattern -> Pattern
+containsPat Empty = ZAny
+containsPat p@ZAny = p
+containsPat p@Not{pat=ZAny} = p
+containsPat p = Contains {
+    pat = p
+    , _nullable = nullable p
+    , _hash = 31 * 17 + hash p
+}
+
+-- | optionalPat is the smart constructor for the optional pattern.
+optionalPat :: Pattern -> Pattern
+optionalPat p@Empty = p
+optionalPat p@Optional{} = p
+optionalPat p = Optional {
+    pat = p
+    , _hash = 31 * 19 + hash p
+}
+
+-- | zeroOrMorePat is the smart constructor for the zeroOrMore pattern.
+zeroOrMorePat :: Pattern -> Pattern
+zeroOrMorePat p@ZeroOrMore{} = p
+zeroOrMorePat p = ZeroOrMore {
+    pat = p
+    , _hash = 31 * 23 + hash p
+}
+
+-- | refPat is the smart constructor for the reference pattern.
+refPat :: M.Map String Bool -> String -> Either String Pattern
+refPat nullRefs name = 
+    case M.lookup name nullRefs of
+        Nothing -> Left $ "no reference named: " ++ name
+        (Just n) -> Right Reference {
+            refName = ValidRef name
+            , _hash = 31 * 29 + Expr.hashString name
+            , _nullable = n
+        }
+
+-- | orPat is the smart constructor for the or pattern.
+orPat :: Pattern -> Pattern -> Pattern
+orPat a b = orPat' $ S.fromList (getOrs a ++ getOrs b)
+
+getOrs :: Pattern -> [Pattern]
+getOrs Or{pats=ps} = ps
+getOrs p = [p]
+
+orPat' :: S.Set Pattern -> Pattern
+orPat' ps = ps `returnIfSingleton`
+    \ps -> if S.member zanyPat ps
+        then zanyPat
+        else S.delete emptySet ps `returnIfSingleton`
+    \ps -> (if all nullable ps
+        then S.delete emptyPat ps
+        else ps) `returnIfSingleton`
+    \ps -> mergeLeaves orExpr ps `returnIfSingleton`
+    \ps -> mergeNodesWithEqualNames orPat ps `returnIfSingleton`
+    \ps -> let psList = sort $ S.toList ps
+    in  Or {
+            pats = psList
+            , _nullable = any nullable psList
+            , _hash = Expr.hashList (31*33) $ map hash psList
+        }
+
+-- | andPat is the smart constructor for the and pattern.
+andPat :: Pattern -> Pattern -> Pattern
+andPat a b = andPat' $ S.fromList (getAnds a ++ getAnds b)
+
+getAnds :: Pattern -> [Pattern]
+getAnds And{pats=ps} = ps
+getAnds p = [p]
+
+andPat' :: S.Set Pattern -> Pattern
+andPat' ps = ps `returnIfSingleton`
+    \ps -> if S.member emptySet ps
+        then emptySet
+        else S.delete zanyPat ps `returnIfSingleton`
+    \ps -> if S.member emptyPat ps
+        then if all nullable ps
+            then emptyPat
+            else emptySet 
+        else ps `returnIfSingleton`
+    \ps -> mergeLeaves andExpr ps `returnIfSingleton`
+    \ps -> mergeNodesWithEqualNames andPat ps `returnIfSingleton`
+    \ps -> let psList = sort $ S.toList ps 
+    in And {
+        pats = psList
+        , _nullable = all nullable psList
+        , _hash = Expr.hashList (31*37) $ map hash psList
+    }
+
+-- | returnIfSingleton returns the pattern from the set if the set is of size one, otherwise it applies the function to the set.
+returnIfSingleton :: S.Set Pattern -> (S.Set Pattern -> Pattern) -> Pattern
+returnIfSingleton s1 f =
+    if S.size s1 == 1 then head $ S.toList s1 else f s1
+
+mergeLeaves :: (Expr.Expr Bool -> Expr.Expr Bool -> Expr.Expr Bool) -> S.Set Pattern -> S.Set Pattern
+mergeLeaves merger = merge $ \a b -> case (a,b) of
+    (Node{expr=ea,pat=Empty},Node{expr=eb,pat=Empty}) -> [nodePat (merger ea eb) emptyPat]
+    _ -> [a,b]
+
+mergeNodesWithEqualNames :: (Pattern -> Pattern -> Pattern) -> S.Set Pattern -> S.Set Pattern
+mergeNodesWithEqualNames merger = merge $ \a b -> case (a,b) of
+    (Node{expr=ea,pat=pa},Node{expr=eb,pat=pb}) -> 
+        if ea == eb then [nodePat ea (merger pa pb)] else [a,b]
+    _ -> [a,b]
+
+merge :: (Pattern -> Pattern -> [Pattern]) -> S.Set Pattern -> S.Set Pattern
+merge merger ps = let list = sortBy leavesThenNamesAndThenContains (S.toList ps)
+    in S.fromList $ foldl (\(a:merged) b -> merger a b ++ merged) [head list] (tail list)
+
+leavesThenNamesAndThenContains :: Pattern -> Pattern -> Ordering
+leavesThenNamesAndThenContains a@Node{} b@Node{} = leavesFirst a b
+leavesThenNamesAndThenContains Node{} _ = LT
+leavesThenNamesAndThenContains _ Node{} = GT
+leavesThenNamesAndThenContains a b = containsThird a b
+
+leavesFirst :: Pattern -> Pattern -> Ordering
+leavesFirst a b
+    | isLeaf a && isLeaf b = compare a b
+    | isLeaf a = LT
+    | isLeaf b = GT
+    | otherwise = namesSecond a b
+
+namesSecond :: Pattern -> Pattern -> Ordering
+namesSecond a@Node{expr=ea} b@Node{expr=eb} = let fcomp = compare ea eb
+    in if fcomp == EQ 
+        then compare a b
+        else fcomp
+
+containsThird :: Pattern -> Pattern -> Ordering
+containsThird a@Contains{} b@Contains{} = compare a b
+containsThird Contains{} _ = LT
+containsThird _ Contains{} = GT
+containsThird a b = compare a b
+
+-- | interleavePat is the smart constructor for the interleave pattern.
+interleavePat :: Pattern -> Pattern -> Pattern
+interleavePat a b = interleavePat' (getInterleaves a ++ getInterleaves b)
+
+getInterleaves :: Pattern -> [Pattern]
+getInterleaves Interleave{pats=ps} = ps
+getInterleaves p = [p]
+
+interleavePat' :: [Pattern] -> Pattern
+interleavePat' ps
+    | emptySet `elem` ps = emptySet
+    | all (eq Empty) ps = emptyPat
+    | otherwise = delete Empty ps `returnIfOnlyOne`
+        \ps -> (if any (eq ZAny) ps
+            then zanyPat : delete ZAny ps
+            else ps) `returnIfOnlyOne`
+        \ps -> let psList = sort ps
+        in Interleave {
+            pats = psList
+            , _nullable = all nullable psList
+            , _hash = Expr.hashList (31*41) $ map hash psList
+        }
+
+-- | returnIfOnlyOne returns the pattern from the list if the list is of size one, otherwise it applies the function to the list.
+returnIfOnlyOne :: [Pattern] -> ([Pattern] -> Pattern) -> Pattern
+returnIfOnlyOne xs f = if length xs == 1 then head xs else f xs
+
+delete :: Pattern -> [Pattern] -> [Pattern]
+delete removeItem = filter (not . (\p -> p == removeItem))
+
+-- |
+-- unescapable is used for short circuiting.
+-- A part of the tree can be skipped if all patterns are unescapable.
+unescapable :: Pattern -> Bool
+unescapable ZAny = True
+unescapable Not{pat=ZAny} = True
+unescapable _ = False
+
+-- |
+-- Grammar is a map from reference name to pattern and describes a relapse grammar.
+newtype Grammar = Grammar Refs
+    deriving (Show, Eq)
+
+-- |
+-- Refs is a map from reference name to pattern, excluding the main reference, which makes a relapse grammar.
+type Refs = M.Map String Pattern
+
+newtype ValidRef = ValidRef String
+    deriving (Eq, Ord, Show)
+
+-- |
+-- lookupRef looks up a pattern in the reference map, given a reference name.
+lookupRef :: Grammar -> ValidRef -> Pattern
+lookupRef (Grammar refs) (ValidRef name) = 
+    case M.lookup name refs of
+        Nothing -> error $ "valid reference not found: " ++ name
+        (Just p) -> p
+
+-- | lookupMain retrieves the main pattern from the grammar.
+lookupMain :: Grammar -> Pattern
+lookupMain g = lookupRef g (ValidRef "main")
diff --git a/src/Data/Katydid/Relapse/VpaDerive.hs b/src/Data/Katydid/Relapse/VpaDerive.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/VpaDerive.hs
@@ -0,0 +1,101 @@
+-- |
+-- This module contains a VPA (Visibly Pushdown Automaton) implementation of the internal derivative algorithm.
+--
+-- It is intended to be used for explanation purposes.
+--
+-- It shows how our algorithm is effectively equivalent to a visibly pushdown automaton.
+
+module Data.Katydid.Relapse.VpaDerive (
+    derive      
+) where
+
+import qualified Data.Map.Strict as M
+import Control.Monad.State (State, runState, state, lift)
+import Data.Foldable (foldlM)
+import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
+
+import Data.Katydid.Parser.Parser
+
+import qualified Data.Katydid.Relapse.Derive as Derive
+import Data.Katydid.Relapse.Smart (Grammar, Pattern)
+import qualified Data.Katydid.Relapse.Smart as Smart
+import Data.Katydid.Relapse.IfExprs
+import Data.Katydid.Relapse.Expr
+import Data.Katydid.Relapse.Zip
+
+mem :: Ord k => (k -> v) -> k -> M.Map k v -> (v, M.Map k v)
+mem f k m
+    | M.member k m = (m M.! k, m)
+    | otherwise = let res = f k
+        in (res, M.insert k res m)
+
+type VpaState = [Pattern]
+type StackElm = ([Pattern], Zipper)
+
+type Calls = M.Map VpaState ZippedIfExprs
+type Nullable = M.Map [Pattern] [Bool]
+type Returns = M.Map ([Pattern], Zipper, [Bool]) [Pattern]
+
+newtype Vpa = Vpa (Nullable, Calls, Returns, Grammar)
+
+newVpa :: Grammar -> Vpa
+newVpa g = Vpa (M.empty, M.empty, M.empty, g)
+
+nullable :: [Pattern] -> State Vpa [Bool]
+nullable key = state $ \(Vpa (n, c, r, g)) -> let (v', n') = mem (map Smart.nullable) key n;
+    in (v', Vpa (n', c, r, g))
+
+calls :: [Pattern] -> State Vpa ZippedIfExprs
+calls key = state $ \(Vpa (n, c, r, g)) -> let (v', c') = mem (zipIfExprs . Derive.calls g) key c;
+    in (v', Vpa (n, c', r, g))
+
+vpacall :: VpaState -> Label -> ExceptT String (State Vpa) (StackElm, VpaState)
+vpacall vpastate label = do {
+    zifexprs <- lift $ calls vpastate;
+    (nextstate, zipper) <- hoistExcept $ evalZippedIfExprs zifexprs label;
+    let 
+        stackelm = (vpastate, zipper)
+    ; 
+    return (stackelm, nextstate)
+}
+
+hoistExcept :: (Monad m) => Either e a -> ExceptT e m a
+hoistExcept = ExceptT . return
+
+returns :: ([Pattern], Zipper, [Bool]) -> State Vpa [Pattern]
+returns key = state $ \(Vpa (n, c, r, g)) -> 
+    let (v', r') = mem (\(ps, zipper, znulls) -> 
+            Derive.returns g (ps, unzipby zipper znulls)) key r
+    in (v', Vpa (n, c, r', g))
+
+vpareturn :: StackElm -> VpaState -> State Vpa VpaState
+vpareturn (vpastate, zipper) current = do {
+    zipnulls <- nullable current;
+    returns (vpastate, zipper, zipnulls)
+}
+
+deriv :: Tree t => VpaState -> t -> ExceptT String (State Vpa) VpaState
+deriv current tree = do {
+    (stackelm, nextstate) <- vpacall current (getLabel tree);
+    resstate <- foldlM deriv nextstate (getChildren tree);
+    lift $ vpareturn stackelm resstate
+}
+
+foldLT :: Tree t => Vpa -> VpaState -> [t] -> Either String [Pattern]
+foldLT _ current [] = return current
+foldLT m current (t:ts) = 
+    let (newstate, newm) = runState (runExceptT $ deriv current t) m
+    in case newstate of
+        (Left l) -> Left l
+        (Right r) -> foldLT newm r ts
+
+-- |
+-- derive is the derivative implementation for trees.
+-- This implementation makes use of visual pushdown automata.
+derive :: Tree t => Grammar -> [t] -> Either String Pattern
+derive g ts = 
+    let start = [Smart.lookupMain g]
+    in case foldLT (newVpa g) start ts of
+        (Left l) -> Left $ show l
+        (Right [r]) -> return r
+        (Right rs) -> Left $ "Number of patterns is not one, but " ++ show rs
diff --git a/src/Data/Katydid/Relapse/Zip.hs b/src/Data/Katydid/Relapse/Zip.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Katydid/Relapse/Zip.hs
@@ -0,0 +1,47 @@
+-- |
+-- This is an internal relapse module.
+--
+-- It zips patterns to reduce the state space.
+
+module Data.Katydid.Relapse.Zip (
+    Zipper, zippy, unzipby
+) where
+
+import qualified Data.Set as S
+import Data.List (elemIndex)
+
+import Data.Katydid.Relapse.Smart
+
+data ZipEntry = ZipVal Int | ZipZAny | ZipNotZAny
+    deriving (Eq, Ord)
+
+-- |
+-- Zipper represents compressed indexes
+-- that resulted from compressing a list of patterns.
+-- This can be used to uncompress a list of bools (nullability of patterns).
+newtype Zipper = Zipper [ZipEntry]
+    deriving (Eq, Ord)
+
+-- | zippy compresses a list of patterns.
+zippy :: [Pattern] -> ([Pattern], Zipper)
+zippy ps =
+    let s = S.fromList ps
+        s' = S.delete ZAny s
+        s'' = S.delete emptySet s'
+        l = S.toAscList s''
+    in (l, Zipper $ map (indexOf l) ps)
+
+indexOf :: [Pattern] -> Pattern -> ZipEntry
+indexOf _ ZAny = ZipZAny
+indexOf _ Not{pat=ZAny} = ZipNotZAny
+indexOf ps p = case elemIndex p ps of
+    (Just i) -> ZipVal i
+
+-- | unzipby uncompresses a list of bools (nullability of patterns).
+unzipby :: Zipper -> [Bool] -> [Bool]
+unzipby (Zipper z) bs = map (ofIndexb bs) z
+
+ofIndexb :: [Bool] -> ZipEntry -> Bool
+ofIndexb _ ZipZAny = True
+ofIndexb _ ZipNotZAny = False
+ofIndexb bs (ZipVal i) = bs !! i
diff --git a/src/Derive.hs b/src/Derive.hs
deleted file mode 100644
--- a/src/Derive.hs
+++ /dev/null
@@ -1,164 +0,0 @@
--- |
--- This module is a simple implementation of the internal derivative algorithm.
---
--- It is intended to be used for explanation purposes.
---
--- This means that it gives up speed for readability.
---
--- Thus it has no type of memoization.
-
-module Derive (
-    derive, calls, returns, zipderive
-    -- * Internal functions
-    -- | These functions are exposed for testing purposes.
-    , removeOneForEach
-) where
-
-import Data.Foldable (foldlM)
-import Data.List.Index (imap)
-
-import Smart
-import Parsers
-import Simplify
-import Zip
-import IfExprs
-
--- | 
--- calls returns a compiled if expression tree.
--- Each if expression returns a child pattern, given the input value.
--- In other words calls signature is actually:
---
--- @
---   Refs -> [Pattern] -> Value -> [Pattern]
--- @
---
--- , where the resulting list of patterns are the child patterns,
--- that need to be derived given the trees child values.
-calls :: Grammar -> [Pattern] -> IfExprs
-calls g ps = compileIfExprs $ concatMap (\p -> deriveCall g p []) ps
-
-deriveCall :: Grammar -> Pattern -> [IfExpr] -> [IfExpr]
-deriveCall _ Empty res = res
-deriveCall _ ZAny res = res
-deriveCall _ Node{expr=v,pat=p} res = newIfExpr v p emptySet : res
-deriveCall g Concat{left=l,right=r} res
-    | nullable l = deriveCall g l (deriveCall g r res)
-    | otherwise = deriveCall g l res
-deriveCall g Or{pats=ps} res = foldr (deriveCall g) res ps
-deriveCall g And{pats=ps} res = foldr (deriveCall g) res ps
-deriveCall g Interleave{pats=ps} res = foldr (deriveCall g) res ps
-deriveCall g ZeroOrMore{pat=p} res = deriveCall g p res
-deriveCall g Reference{refName=name} res = deriveCall g (lookupRef g name) res
-deriveCall g Not{pat=p} res = deriveCall g p res
-deriveCall g Contains{pat=p} res = deriveCall g p res
-deriveCall g Optional{pat=p} res = deriveCall g p res
-
--- |
--- returns takes a list of patterns and list of bools.
--- The list of bools represent the nullability of the derived child patterns.
--- Each bool will then replace each Node pattern with either an Empty or EmptySet.
--- The lists do not to be the same length, because each Pattern can contain an arbitrary number of Node Patterns.
-returns :: Grammar -> ([Pattern], [Bool]) -> [Pattern]
-returns _ ([], []) = []
-returns g (p:tailps, ns) =
-    let (dp, tailns) = deriveReturn g p ns
-    in  dp:returns g (tailps, tailns)
-
-mapReturn :: Grammar -> [Pattern] -> [Bool] -> ([Pattern], [Bool])
-mapReturn g ps ns = foldl (\(dps, tailns) p ->
-        let (dp, tailoftail) = deriveReturn g p tailns
-        in (dp:dps, tailoftail)
-    ) ([], ns) ps
-
-deriveReturn :: Grammar -> Pattern -> [Bool] -> (Pattern, [Bool])
-deriveReturn _ Empty ns = (emptySet, ns)
-deriveReturn _ ZAny ns = (zanyPat, ns)
-deriveReturn _ Node{} ns
-    | head ns = (emptyPat, tail ns)
-    | otherwise = (emptySet, tail ns)
-deriveReturn g Concat{left=l,right=r} ns
-    | nullable l =
-        let (dl, ltail) = deriveReturn g l ns
-            (dr, rtail) = deriveReturn g r ltail
-        in  (orPat (concatPat dl r) dr, rtail)
-    | otherwise =
-        let (dl, ltail) = deriveReturn g l ns
-        in  (concatPat dl r, ltail)
-deriveReturn g Or{pats=ps} ns =
-    let (dps, tailns) = mapReturn g ps ns
-    in (foldl1 orPat dps, tailns)
-deriveReturn g And{pats=ps} ns =
-    let (dps, tailns) = mapReturn g ps ns
-    in (foldl1 andPat dps, tailns)
-deriveReturn g Interleave{pats=ps} ns =
-    let (dps, tailns) = mapReturn g ps ns
-        pps = reverse $ removeOneForEach ps
-        ips = zipWith (:) dps pps
-        ors = map (foldl1 interleavePat) ips
-    in (foldl1 orPat ors, tailns)
-deriveReturn g z@ZeroOrMore{pat=p} ns =
-    let (dp, tailns) = deriveReturn g p ns
-    in  (concatPat dp z, tailns)
-deriveReturn g Reference{refName=name} ns = deriveReturn g (lookupRef g name) ns
-deriveReturn g Not{pat=p} ns =
-    let (dp, tailns) = deriveReturn g p ns
-    in  (notPat dp, tailns)
-deriveReturn g c@Contains{pat=p} ns =
-    let (dp, tailns) = deriveReturn g p ns
-    in  (orPat c (containsPat dp), tailns)
-deriveReturn g Optional{pat=p} ns = deriveReturn g p ns
-
--- | For internal testing.
--- removeOneForEach creates N copies of the list removing the n'th element from each.
-removeOneForEach :: [a] -> [[a]]
-removeOneForEach xs = imap (\index list ->
-        let (start,end) = splitAt index list
-        in start ++ tail end
-    ) (replicate (length xs) xs)
-
--- |
--- derive is the classic derivative implementation for trees.
-derive :: Tree t => Grammar -> [t] -> Either String Pattern
-derive g ts = do {
-    ps <- foldlM (deriv g) [lookupMain g] ts;
-    if length ps == 1 
-        then return $ head ps
-        else Left $ "Number of patterns is not one, but " ++ show ps
-}
-
-deriv :: Tree t => Grammar -> [Pattern] -> t -> Either String [Pattern]
-deriv g ps tree =
-    if all unescapable ps then return ps else
-    let ifs = calls g ps
-        d = deriv g
-        nulls = map nullable
-    in do {
-        childps <- evalIfExprs ifs (getLabel tree);
-        childres <- foldlM d childps (getChildren tree);
-        return $ returns g (ps, nulls childres);
-    }
-
--- |
--- zipderive is a slighty optimized version of derivs.
--- It zips its intermediate pattern lists to reduce the state space.
-zipderive :: Tree t => Grammar -> [t] -> Either String Pattern
-zipderive g ts = do {
-    ps <- foldlM (zipderiv g) [lookupMain g] ts;
-    if length ps == 1 
-        then return $ head ps
-        else Left $ "Number of patterns is not one, but " ++ show ps
-}
-
-zipderiv :: Tree t => Grammar -> [Pattern] -> t -> Either String [Pattern]
-zipderiv g ps tree =
-    if all unescapable ps then return ps else
-    let ifs = calls g ps
-        d = zipderiv g
-        nulls = map nullable
-    in do {
-        childps <- evalIfExprs ifs (getLabel tree);
-        (zchildps, zipper) <- return $ zippy childps;
-        childres <- foldlM d zchildps (getChildren tree);
-        let unzipns = unzipby zipper (nulls childres)
-        in return $ returns g (ps, unzipns)
-    }
diff --git a/src/Expr.hs b/src/Expr.hs
deleted file mode 100644
--- a/src/Expr.hs
+++ /dev/null
@@ -1,509 +0,0 @@
--- |
--- This module contains all the functions you need to implement a Relapse expression.
-
-module Expr (
-    Desc(..), mkDesc
-    , AnyExpr(..), AnyFunc(..)
-    , Expr(..), Func, params, name, hasVar
-    , hashWithName, hashList, hashString
-    , evalConst, isConst
-    , assertArgs1, assertArgs2
-    , mkBoolExpr, mkIntExpr, mkStringExpr, mkDoubleExpr, mkBytesExpr, mkUintExpr
-    , assertBool, assertInt, assertString, assertDouble, assertBytes, assertUint
-    , boolExpr, intExpr, stringExpr, doubleExpr, bytesExpr, uintExpr
-    , trimBool, trimInt, trimString, trimDouble, trimBytes, trimUint
-    , mkBoolsExpr, mkIntsExpr, mkStringsExpr, mkDoublesExpr, mkListOfBytesExpr, mkUintsExpr
-    , assertBools, assertInts, assertStrings, assertDoubles, assertListOfBytes, assertUints
-    , boolsExpr, intsExpr, stringsExpr, doublesExpr, listOfBytesExpr, uintsExpr
-) where
-
-import Data.Char (ord)
-import Data.List (intercalate)
-import Data.Text (Text, unpack, pack)
-import Data.ByteString (ByteString)
-
-import qualified Parsers
-
--- |
--- assertArgs1 asserts that the list of arguments is only one argument and 
--- returns the argument or an error message 
--- containing the function name that was passed in as an argument to assertArgs1.
-assertArgs1 :: String -> [AnyExpr] -> Either String AnyExpr
-assertArgs1 _ [e1] = Right e1
-assertArgs1 exprName es = Left $ exprName ++ ": expected one argument, but got " ++ show (length es) ++ ": " ++ show es
-
--- |
--- assertArgs2 asserts that the list of arguments is only two arguments and 
--- returns the two arguments or an error message 
--- containing the function name that was passed in as an argument to assertArgs2.
-assertArgs2 :: String -> [AnyExpr] -> Either String (AnyExpr, AnyExpr)
-assertArgs2 _ [e1, e2] = Right (e1, e2)
-assertArgs2 exprName es = Left $ exprName ++ ": expected two arguments, but got " ++ show (length es) ++ ": " ++ show es
-
--- |
--- Desc is the description of a function, 
--- especially built to make comparisons of user defined expressions possible.
-data Desc = Desc {
-    _name :: String
-    , _toStr :: String
-    , _hash :: Int
-    , _params :: [Desc]
-    , _hasVar :: Bool
-}
-
--- |
--- mkDesc makes a description from a function name and a list of the argument's descriptions.
-mkDesc :: String -> [Desc] -> Desc
-mkDesc n ps = Desc {
-    _name = n
-    , _toStr = n ++ "(" ++ intercalate "," (map show ps) ++ ")"
-    , _hash = hashWithName n ps
-    , _params = ps
-    , _hasVar = any _hasVar ps
-}
-
-instance Show Desc where
-    show = _toStr
-
-instance Ord Desc where
-    compare = cmp
-
-instance Eq Desc where
-    (==) a b = cmp a b == EQ
-
--- |
--- AnyExpr is used by the Relapse parser to represent an Expression that can return any type of value, 
--- where any is a predefined list of possible types represented by AnyFunc.
-data AnyExpr = AnyExpr {
-    _desc :: Desc
-    , _eval :: AnyFunc
-}
-
--- |
--- Func represents the evaluation function part of a user defined expression.
--- This function takes a label from a tree parser and returns a value or an error string.
-type Func a = (Parsers.Label -> Either String a)
-
-instance Show AnyExpr where
-    show a = show (_desc a)
-
-instance Eq AnyExpr where
-    (==) a b = _desc a == _desc b
-
-instance Ord AnyExpr where
-    compare a b = cmp (_desc a) (_desc b)
-
--- |
--- AnyFunc is used by the Relapse parser and represents the list all supported types of functions.
-data AnyFunc = BoolFunc (Func Bool)
-    | IntFunc (Func Int)
-    | StringFunc (Func Text)
-    | DoubleFunc (Func Double)
-    | UintFunc (Func Word)
-    | BytesFunc (Func ByteString)
-    | BoolsFunc (Func [Bool])
-    | IntsFunc (Func [Int])
-    | StringsFunc (Func [Text])
-    | DoublesFunc (Func [Double])
-    | UintsFunc (Func [Word])
-    | ListOfBytesFunc (Func [ByteString])
-
--- |
--- Expr represents a user defined expression, 
--- which consists of a description for comparisons and an evaluation function.
-data Expr a = Expr {
-    desc :: Desc
-    , eval :: Func a
-}
-
-instance Show (Expr a) where
-    show e = show (desc e)
-
-instance Eq (Expr a) where
-    (==) x y = desc x == desc y
-
-instance Ord (Expr a) where
-    compare x y = cmp (desc x) (desc y)
-
--- |
--- params returns the descriptions of the parameters of the user defined expression.
-params :: Expr a -> [Desc]
-params = _params . desc
-
--- |
--- name returns the name of the user defined expression.
-name :: Expr a -> String
-name = _name . desc
-
--- |
--- hasVar returns whether the expression or any of its children contains a variable expression.
-hasVar :: Expr a -> Bool
-hasVar = _hasVar . desc
-
--- |
--- mkBoolExpr generalises a bool expression to any expression.
-mkBoolExpr :: Expr Bool -> AnyExpr
-mkBoolExpr (Expr desc eval) = AnyExpr desc (BoolFunc eval)
-
--- |
--- assertBool asserts that any expression is actually a bool expression.
-assertBool :: AnyExpr -> Either String (Expr Bool)
-assertBool (AnyExpr desc (BoolFunc eval)) = Right $ Expr desc eval
-assertBool (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type bool"
-
--- |
--- mkIntExpr generalises an int expression to any expression.
-mkIntExpr :: Expr Int -> AnyExpr
-mkIntExpr (Expr desc eval) = AnyExpr desc (IntFunc eval)
-
--- |
--- assertInt asserts that any expression is actually an int expression.
-assertInt :: AnyExpr -> Either String (Expr Int)
-assertInt (AnyExpr desc (IntFunc eval)) = Right $ Expr desc eval
-assertInt (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type int"
-
--- |
--- mkDoubleExpr generalises a double expression to any expression.
-mkDoubleExpr :: Expr Double -> AnyExpr
-mkDoubleExpr (Expr desc eval) = AnyExpr desc (DoubleFunc eval)
-
--- |
--- assertDouble asserts that any expression is actually a double expression.
-assertDouble :: AnyExpr -> Either String (Expr Double)
-assertDouble (AnyExpr desc (DoubleFunc eval)) = Right $ Expr desc eval
-assertDouble (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type double"
-
--- |
--- mkStringExpr generalises a string expression to any expression.
-mkStringExpr :: Expr Text -> AnyExpr
-mkStringExpr (Expr desc eval) = AnyExpr desc (StringFunc eval)
-
--- |
--- assertString asserts that any expression is actually a string expression.
-assertString :: AnyExpr -> Either String (Expr Text)
-assertString (AnyExpr desc (StringFunc eval)) = Right $ Expr desc eval
-assertString (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type string"
-
--- |
--- mkUintExpr generalises a uint expression to any expression.
-mkUintExpr :: Expr Word -> AnyExpr
-mkUintExpr (Expr desc eval) = AnyExpr desc (UintFunc eval)
-
--- |
--- assertUint asserts that any expression is actually a uint expression.
-assertUint :: AnyExpr -> Either String (Expr Word)
-assertUint (AnyExpr desc (UintFunc eval)) = Right $ Expr desc eval
-assertUint (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type uint"
-
--- |
--- mkBytesExpr generalises a bytes expression to any expression.
-mkBytesExpr :: Expr ByteString -> AnyExpr
-mkBytesExpr (Expr desc eval) = AnyExpr desc (BytesFunc eval)
-
--- |
--- assertBytes asserts that any expression is actually a bytes expression.
-assertBytes :: AnyExpr -> Either String (Expr ByteString)
-assertBytes (AnyExpr desc (BytesFunc eval)) = Right $ Expr desc eval
-assertBytes (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type bytes"
-
--- |
--- mkBoolsExpr generalises a list of bools expression to any expression.
-mkBoolsExpr :: Expr [Bool] -> AnyExpr
-mkBoolsExpr (Expr desc eval) = AnyExpr desc (BoolsFunc eval)
-
--- |
--- assertBools asserts that any expression is actually a list of bools expression.
-assertBools :: AnyExpr -> Either String (Expr [Bool])
-assertBools (AnyExpr desc (BoolsFunc eval)) = Right $ Expr desc eval
-assertBools (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type bools"
-
--- |
--- mkIntsExpr generalises a list of ints expression to any expression.
-mkIntsExpr :: Expr [Int] -> AnyExpr
-mkIntsExpr (Expr desc eval) = AnyExpr desc (IntsFunc eval)
-
--- |
--- assertInts asserts that any expression is actually a list of ints expression.
-assertInts :: AnyExpr -> Either String (Expr [Int])
-assertInts (AnyExpr desc (IntsFunc eval)) = Right $ Expr desc eval
-assertInts (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type ints"
-
--- |
--- mkUintsExpr generalises a list of uints expression to any expression.
-mkUintsExpr :: Expr [Word] -> AnyExpr
-mkUintsExpr (Expr desc eval) = AnyExpr desc (UintsFunc eval)
-
--- |
--- assertUints asserts that any expression is actually a list of uints expression.
-assertUints :: AnyExpr -> Either String (Expr [Word])
-assertUints (AnyExpr desc (UintsFunc eval)) = Right $ Expr desc eval
-assertUints (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type uints"
-
--- |
--- mkDoublesExpr generalises a list of doubles expression to any expression.
-mkDoublesExpr :: Expr [Double] -> AnyExpr
-mkDoublesExpr (Expr desc eval) = AnyExpr desc (DoublesFunc eval)
-
--- |
--- assertDoubles asserts that any expression is actually a list of doubles expression.
-assertDoubles :: AnyExpr -> Either String (Expr [Double])
-assertDoubles (AnyExpr desc (DoublesFunc eval)) = Right $ Expr desc eval
-assertDoubles (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type doubles"
-
--- |
--- mkStringsExpr generalises a list of strings expression to any expression.
-mkStringsExpr :: Expr [Text] -> AnyExpr
-mkStringsExpr (Expr desc eval) = AnyExpr desc (StringsFunc eval)
-
--- |
--- assertStrings asserts that any expression is actually a list of strings expression.
-assertStrings :: AnyExpr -> Either String (Expr [Text])
-assertStrings (AnyExpr desc (StringsFunc eval)) = Right $ Expr desc eval
-assertStrings (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type strings"
-
--- |
--- mkListOfBytesExpr generalises a list of bytes expression to any expression.
-mkListOfBytesExpr :: Expr [ByteString] -> AnyExpr
-mkListOfBytesExpr (Expr desc eval) = AnyExpr desc (ListOfBytesFunc eval)
-
--- |
--- assertListOfBytes asserts that any expression is actually a list of bytes expression.
-assertListOfBytes :: AnyExpr -> Either String (Expr [ByteString])
-assertListOfBytes (AnyExpr desc (ListOfBytesFunc eval)) = Right $ Expr desc eval
-assertListOfBytes (AnyExpr desc _) = Left $ "expected <" ++ show desc ++ "> to be of type bytes"
-
--- cmp is an efficient comparison function for expressions.
--- It is very important that cmp is efficient, 
--- because it is a bottleneck for simplification and smart construction of large queries.
-cmp :: Desc -> Desc -> Ordering
-cmp a b = compare (_hash a) (_hash b) <>
-    compare (_name a) (_name b) <>
-    compare (length (_params a)) (length (_params b)) <>
-    foldl (<>) EQ (zipWith cmp (_params a) (_params b)) <>
-    compare (_toStr a) (_toStr b)
-
--- |
--- hashWithName calculates a hash of the function name and its parameters.
-hashWithName :: String -> [Desc] -> Int
-hashWithName s ds = hashList (31*17 + hashString s) (map _hash ds)
-
--- |
--- hashString calcuates a hash of a string.
-hashString :: String -> Int
-hashString s = hashList 0 (map ord s)
-
--- |
--- hashList folds a list of hashes into one, given a seed and the list.
-hashList :: Int -> [Int] -> Int
-hashList = foldl (\acc h -> 31*acc + h)
-
-noLabel :: Parsers.Label
-noLabel = Parsers.String (pack "not a label, trying constant evaluation")
-
--- |
--- evalConst tries to evaluate a constant expression and 
--- either returns the resulting constant value or nothing.
-evalConst :: Expr a -> Maybe a
-evalConst e = if hasVar e
-    then Nothing
-    else case eval e noLabel of
-        (Left _) -> Nothing
-        (Right v) -> Just v
-
--- |
--- isConst returns whether the input description is one of the six possible constant values.
-isConst :: Desc -> Bool
-isConst d = not (null (_params d)) && case _name d of
-    "bool" -> True
-    "int" -> True
-    "uint" -> True
-    "double" -> True
-    "string" -> True
-    "[]byte" -> True
-    _ -> False
-
--- |
--- boolExpr creates a constant bool expression from a input value.
-boolExpr :: Bool -> Expr Bool 
-boolExpr b = Expr {
-    desc = Desc {
-        _name = "bool"
-        , _toStr = if b then "true" else "false"
-        , _hash = if b then 3 else 5
-        , _params = []
-        , _hasVar = False
-    }
-    , eval = const $ return b
-}
-
--- |
--- intExpr creates a constant int expression from a input value.
-intExpr :: Int -> Expr Int
-intExpr i = Expr {
-    desc = Desc {
-        _name = "int"
-        , _toStr = show i
-        , _hash = i
-        , _params = []
-        , _hasVar = False
-    }
-    , eval = const $ return i
-}
-
--- |
--- doubleExpr creates a constant double expression from a input value.
-doubleExpr :: Double -> Expr Double
-doubleExpr d = Expr {
-    desc = Desc {
-        _name = "double"
-        , _toStr = show d
-        , _hash = truncate d
-        , _params = []
-        , _hasVar = False
-    }
-    , eval = const $ return d
-}
-
--- |
--- uintExpr creates a constant uint expression from a input value.
-uintExpr :: Word -> Expr Word
-uintExpr i = Expr {
-    desc = Desc {
-        _name = "uint"
-        , _toStr = show i
-        , _hash = hashString (show i)
-        , _params = []
-        , _hasVar = False
-    }
-    , eval = const $ return i
-}
-
--- |
--- stringExpr creates a constant string expression from a input value.
-stringExpr :: Text -> Expr Text
-stringExpr s = Expr {
-    desc = Desc {
-        _name = "string"
-        , _toStr = show s
-        , _hash = hashString (unpack s)
-        , _params = []
-        , _hasVar = False
-    }
-    , eval = const $ return s
-}
-
--- |
--- bytesExpr creates a constant bytes expression from a input value.
-bytesExpr :: ByteString -> Expr ByteString
-bytesExpr b = Expr {
-    desc = Desc {
-        _name = "bytes"
-        , _toStr = "[]byte{" ++ show b ++ "}"
-        , _hash = hashString (show b)
-        , _params = []
-        , _hasVar = False
-    }
-    , eval = const $ return b
-}
-
--- |
--- trimBool tries to reduce an expression to a single constant expression,
--- if it does not contain a variable.
-trimBool :: Expr Bool -> Expr Bool
-trimBool e = if hasVar e 
-    then e
-    else case eval e noLabel of
-        (Left _) -> e
-        (Right v) -> boolExpr v
-
--- |
--- trimInt tries to reduce an expression to a single constant expression,
--- if it does not contain a variable.
-trimInt :: Expr Int -> Expr Int
-trimInt e = if hasVar e 
-    then e
-    else case eval e noLabel of
-        (Left _) -> e
-        (Right v) -> intExpr v
-
--- |
--- trimUint tries to reduce an expression to a single constant expression,
--- if it does not contain a variable.
-trimUint :: Expr Word -> Expr Word
-trimUint e = if hasVar e 
-    then e
-    else case eval e noLabel of
-        (Left _) -> e
-        (Right v) -> uintExpr v
-
--- |
--- trimString tries to reduce an expression to a single constant expression,
--- if it does not contain a variable.
-trimString :: Expr Text -> Expr Text
-trimString e = if hasVar e 
-    then e
-    else case eval e noLabel of
-        (Left _) -> e
-        (Right v) -> stringExpr v
-
--- |
--- trimDouble tries to reduce an expression to a single constant expression,
--- if it does not contain a variable.
-trimDouble :: Expr Double -> Expr Double
-trimDouble e = if hasVar e 
-    then e
-    else case eval e noLabel of
-        (Left _) -> e
-        (Right v) -> doubleExpr v
-
--- |
--- trimBytes tries to reduce an expression to a single constant expression,
--- if it does not contain a variable.
-trimBytes :: Expr ByteString -> Expr ByteString
-trimBytes e = if hasVar e 
-    then e
-    else case eval e noLabel of
-        (Left _) -> e
-        (Right v) -> bytesExpr v
-
--- |
--- boolsExpr sequences a list of expressions that each return a bool, 
--- to a single expression that returns a list of bools.
-boolsExpr :: [Expr Bool] -> Expr [Bool]
-boolsExpr = seqExprs "[]bool" 
-
--- |
--- intsExpr sequences a list of expressions that each return an int, 
--- to a single expression that returns a list of ints.
-intsExpr :: [Expr Int] -> Expr [Int]
-intsExpr = seqExprs "[]int"
-
--- |
--- stringsExpr sequences a list of expressions that each return a string, 
--- to a single expression that returns a list of strings.
-stringsExpr :: [Expr Text] -> Expr [Text]
-stringsExpr = seqExprs "[]string"
-
--- |
--- doublesExpr sequences a list of expressions that each return a double, 
--- to a single expression that returns a list of doubles.
-doublesExpr :: [Expr Double] -> Expr [Double]
-doublesExpr = seqExprs "[]double"
-
--- |
--- listOfBytesExpr sequences a list of expressions that each return bytes, 
--- to a single expression that returns a list of bytes.
-listOfBytesExpr :: [Expr ByteString] -> Expr [ByteString]
-listOfBytesExpr = seqExprs "[][]byte"
-
--- |
--- uintsExpr sequences a list of expressions that each return a uint, 
--- to a single expression that returns a list of uints.
-uintsExpr :: [Expr Word] -> Expr [Word]
-uintsExpr = seqExprs "[]uint"
-
-seqExprs :: String -> [Expr a] -> Expr [a]
-seqExprs n es = Expr {
-    desc = mkDesc n (map desc es)
-    , eval = \v -> mapM (`eval` v) es
-}
diff --git a/src/Exprs.hs b/src/Exprs.hs
deleted file mode 100644
--- a/src/Exprs.hs
+++ /dev/null
@@ -1,86 +0,0 @@
--- |
--- This module contains the standard library of expressions, used by the Relapse parser.
-
-module Exprs (
-    mkBuiltIn
-    , mkExpr
-    , MkFunc
-    , stdOnly
-) where
-
-import Expr
-import Exprs.Compare
-import Exprs.Contains
-import Exprs.Elem
-import Exprs.Length
-import Exprs.Logic
-import Exprs.Strings
-import Exprs.Type
-import Exprs.Var
-
--- |
--- MkFunc is used by the parser to create a function from a name and arguments.
-type MkFunc = String -> [AnyExpr] -> Either String AnyExpr
-
--- |
--- mkExpr is a grouping of all the standard library functions as one MkFunc.
-mkExpr :: String -> [AnyExpr] -> Either String AnyExpr
-mkExpr "eq" es = mkEqExpr es
-mkExpr "ne" es = mkNeExpr es
-mkExpr "ge" es = mkGeExpr es
-mkExpr "gt" es = mkGtExpr es
-mkExpr "le" es = mkLeExpr es
-mkExpr "lt" es = mkLtExpr es
-mkExpr "contains" es = mkContainsExpr es
-mkExpr "elem" es = mkElemExpr es
-mkExpr "length" es = mkLengthExpr es
-mkExpr "not" es = mkNotExpr es
-mkExpr "and" es = mkAndExpr es
-mkExpr "or" es = mkOrExpr es
-mkExpr "hasPrefix" es = mkHasPrefixExpr es
-mkExpr "hasSuffix" es = mkHasSuffixExpr es
-mkExpr "regex" es = mkRegexExpr es
-mkExpr "toLower" es = mkToLowerExpr es
-mkExpr "toUpper" es = mkToUpperExpr es
-mkExpr "type" es = mkTypeExpr es
-mkExpr n _ = Left $ "unknown function: " ++ n
-
--- |
--- stdOnly contains no functions, which means that when it is combined 
--- (in Relapse parser) with mkExpr the parser will have access to only the standard library.
-stdOnly :: String -> [AnyExpr] -> Either String AnyExpr
-stdOnly n _ = Left $ "unknown function: " ++ n
-
--- |
--- mkBuiltIn parsers a builtin function to a relapse expression.
-mkBuiltIn :: String -> AnyExpr -> Either String AnyExpr
-mkBuiltIn symbol constExpr = funcName symbol >>= (\n ->
-        if n == "type" then
-            mkExpr n [constExpr]
-        else if n == "regex" then
-            mkExpr n [constExpr, constToVar constExpr]
-        else
-            mkExpr n [constToVar constExpr, constExpr]
-    )
-
-funcName :: String -> Either String String
-funcName "==" = return "eq"
-funcName "!=" = return "ne"
-funcName "<" = return "lt"
-funcName ">" = return "gt"
-funcName "<=" = return "le"
-funcName ">=" = return "ge"
-funcName "~=" = return "regex"
-funcName "*=" = return "contains"
-funcName "^=" = return "hasPrefix"
-funcName "$=" = return "hasSuffix"
-funcName "::" = return "type"
-funcName n = fail $ "unexpected funcName: <" ++ n ++ ">"
-
-constToVar :: AnyExpr -> AnyExpr
-constToVar (AnyExpr _ (BoolFunc _)) = mkBoolExpr varBoolExpr
-constToVar (AnyExpr _ (IntFunc _)) = mkIntExpr varIntExpr
-constToVar (AnyExpr _ (UintFunc _)) = mkUintExpr varUintExpr
-constToVar (AnyExpr _ (DoubleFunc _)) = mkDoubleExpr varDoubleExpr
-constToVar (AnyExpr _ (StringFunc _)) = mkStringExpr varStringExpr
-constToVar (AnyExpr _ (BytesFunc _)) = mkBytesExpr varBytesExpr
diff --git a/src/Exprs/Compare.hs b/src/Exprs/Compare.hs
deleted file mode 100644
--- a/src/Exprs/Compare.hs
+++ /dev/null
@@ -1,191 +0,0 @@
--- |
--- This module contains the Relapse compare expressions: 
--- equal, not equal, greater than, greater than or equal, less than and less than or equal.
-module Exprs.Compare (
-    mkEqExpr, eqExpr
-    , mkNeExpr, neExpr
-    , mkGeExpr, geExpr
-    , mkLeExpr, leExpr
-    , mkGtExpr, gtExpr
-    , mkLtExpr, ltExpr
-) where
-
-import Expr
-
--- |
--- mkEqExpr dynamically creates an eq (equal) expression, if the two input types are the same.
-mkEqExpr :: [AnyExpr] -> Either String AnyExpr
-mkEqExpr es = do {
-    (e1, e2) <- assertArgs2 "eq" es;
-    case e1 of
-    (AnyExpr _ (BoolFunc _)) -> mkEqExpr' <$> assertBool e1 <*> assertBool e2
-    (AnyExpr _ (IntFunc _)) -> mkEqExpr' <$> assertInt e1 <*> assertInt e2
-    (AnyExpr _ (UintFunc _)) ->  mkEqExpr' <$> assertUint e1 <*> assertUint e2
-    (AnyExpr _ (DoubleFunc _)) -> mkEqExpr' <$> assertDouble e1 <*> assertDouble e2
-    (AnyExpr _ (StringFunc _)) -> mkEqExpr' <$> assertString e1 <*> assertString e2
-    (AnyExpr _ (BytesFunc _)) -> mkEqExpr' <$> assertBytes e1 <*> assertBytes e2
-}
-
-mkEqExpr' :: (Eq a) => Expr a -> Expr a -> AnyExpr
-mkEqExpr' e f = mkBoolExpr $ eqExpr e f
-
--- |
--- eqExpr creates an eq (equal) expression that returns true if the two evaluated input expressions are equal
--- and both don't evaluate to an error.
-eqExpr :: (Eq a) => Expr a -> Expr a -> Expr Bool
-eqExpr a b = trimBool Expr {
-    desc = mkDesc "eq" [desc a, desc b]
-    , eval = \v -> eq (eval a v) (eval b v)
-}
-
-eq :: (Eq a) => Either String a -> Either String a -> Either String Bool
-eq (Right v1) (Right v2) = return $ v1 == v2
-eq (Left _) _ = return False
-eq _ (Left _) = return False
-
--- |
--- mkNeExpr dynamically creates a ne (not equal) expression, if the two input types are the same.
-mkNeExpr :: [AnyExpr] -> Either String AnyExpr
-mkNeExpr es = do {
-    (e1, e2) <- assertArgs2 "ne" es;
-    case e1 of
-    (AnyExpr _ (BoolFunc _)) -> mkNeExpr' <$> assertBool e1 <*> assertBool e2
-    (AnyExpr _ (IntFunc _)) -> mkNeExpr' <$> assertInt e1 <*> assertInt e2
-    (AnyExpr _ (UintFunc _)) ->  mkNeExpr' <$> assertUint e1 <*> assertUint e2
-    (AnyExpr _ (DoubleFunc _)) -> mkNeExpr' <$> assertDouble e1 <*> assertDouble e2
-    (AnyExpr _ (StringFunc _)) -> mkNeExpr' <$> assertString e1 <*> assertString e2
-    (AnyExpr _ (BytesFunc _)) -> mkNeExpr' <$> assertBytes e1 <*> assertBytes e2
-}
-
-mkNeExpr' :: (Eq a) => Expr a -> Expr a -> AnyExpr
-mkNeExpr' e f = mkBoolExpr $ neExpr e f
-
--- |
--- neExpr creates a ne (not equal) expression that returns true if the two evaluated input expressions are not equal
--- and both don't evaluate to an error.
-neExpr :: (Eq a) => Expr a -> Expr a -> Expr Bool
-neExpr a b = trimBool Expr {
-    desc = mkDesc "ne" [desc a, desc b]
-    , eval = \v -> ne (eval a v) (eval b v)
-}
-
-ne :: (Eq a) => Either String a -> Either String a -> Either String Bool
-ne (Right v1) (Right v2) = return $ v1 /= v2
-ne (Left _) _ = return False
-ne _ (Left _) = return False
-
--- |
--- mkGeExpr dynamically creates a ge (greater than or equal) expression, if the two input types are the same.
-mkGeExpr :: [AnyExpr] -> Either String AnyExpr
-mkGeExpr es = do {
-    (e1, e2) <- assertArgs2 "ge" es;
-    case e1 of
-    (AnyExpr _ (IntFunc _)) -> mkGeExpr' <$> assertInt e1 <*> assertInt e2
-    (AnyExpr _ (UintFunc _)) ->  mkGeExpr' <$> assertUint e1 <*> assertUint e2
-    (AnyExpr _ (DoubleFunc _)) -> mkGeExpr' <$> assertDouble e1 <*> assertDouble e2
-    (AnyExpr _ (BytesFunc _)) -> mkGeExpr' <$> assertBytes e1 <*> assertBytes e2
-}
-
-mkGeExpr' :: (Ord a) => Expr a -> Expr a -> AnyExpr
-mkGeExpr' e f = mkBoolExpr $ geExpr e f
-
--- |
--- geExpr creates a ge (greater than or equal) expression that returns true if the first evaluated expression is greater than or equal to the second
--- and both don't evaluate to an error.
-geExpr :: (Ord a) => Expr a -> Expr a -> Expr Bool
-geExpr a b = trimBool Expr {
-    desc = mkDesc "ge" [desc a, desc b]
-    , eval = \v -> ge (eval a v) (eval b v)
-}
-
-ge :: (Ord a) => Either String a -> Either String a -> Either String Bool
-ge (Right v1) (Right v2) = return $ v1 >= v2
-ge (Left _) _ = return False
-ge _ (Left _) = return False
-
--- |
--- mkGtExpr dynamically creates a gt (greater than) expression, if the two input types are the same.
-mkGtExpr :: [AnyExpr] -> Either String AnyExpr
-mkGtExpr es = do {
-    (e1, e2) <- assertArgs2 "gt" es;
-    case e1 of
-    (AnyExpr _ (IntFunc _)) -> mkGtExpr' <$> assertInt e1 <*> assertInt e2
-    (AnyExpr _ (UintFunc _)) ->  mkGtExpr' <$> assertUint e1 <*> assertUint e2
-    (AnyExpr _ (DoubleFunc _)) -> mkGtExpr' <$> assertDouble e1 <*> assertDouble e2
-    (AnyExpr _ (BytesFunc _)) -> mkGtExpr' <$> assertBytes e1 <*> assertBytes e2
-}
-
-mkGtExpr' :: (Ord a) => Expr a -> Expr a -> AnyExpr
-mkGtExpr' e f = mkBoolExpr $ gtExpr e f
-
--- |
--- gtExpr creates a gt (greater than) expression that returns true if the first evaluated expression is greater than the second
--- and both don't evaluate to an error.
-gtExpr :: (Ord a) => Expr a -> Expr a -> Expr Bool
-gtExpr a b = trimBool Expr {
-    desc = mkDesc "gt" [desc a, desc b]
-    , eval = \v -> gt (eval a v) (eval b v)
-}
-
-gt :: (Ord a) => Either String a -> Either String a -> Either String Bool
-gt (Right v1) (Right v2) = return $ v1 > v2
-gt (Left _) _ = return False
-gt _ (Left _) = return False
-
--- |
--- mkLeExpr dynamically creates a le (less than or equal) expression, if the two input types are the same.
-mkLeExpr :: [AnyExpr] -> Either String AnyExpr
-mkLeExpr es = do {
-    (e1, e2) <- assertArgs2 "le" es;
-    case e1 of
-    (AnyExpr _ (IntFunc _)) -> mkLeExpr' <$> assertInt e1 <*> assertInt e2
-    (AnyExpr _ (UintFunc _)) ->  mkLeExpr' <$> assertUint e1 <*> assertUint e2
-    (AnyExpr _ (DoubleFunc _)) -> mkLeExpr' <$> assertDouble e1 <*> assertDouble e2
-    (AnyExpr _ (BytesFunc _)) -> mkLeExpr' <$> assertBytes e1 <*> assertBytes e2
-}
-
-mkLeExpr' :: (Ord a) => Expr a -> Expr a -> AnyExpr
-mkLeExpr' e f = mkBoolExpr $ leExpr e f
-
--- |
--- leExpr creates a le (less than or equal) expression that returns true if the first evaluated expression is less than or equal to the second
--- and both don't evaluate to an error.
-leExpr :: (Ord a) => Expr a -> Expr a -> Expr Bool
-leExpr a b = trimBool Expr {
-    desc = mkDesc "le" [desc a, desc b]
-    , eval = \v -> le (eval a v) (eval b v)
-}
-
-le :: (Ord a) => Either String a -> Either String a -> Either String Bool
-le (Right v1) (Right v2) = return $ v1 <= v2
-le (Left _) _ = return False
-le _ (Left _) = return False
-
--- |
--- mkLtExpr dynamically creates a lt (less than) expression, if the two input types are the same.
-mkLtExpr :: [AnyExpr] -> Either String AnyExpr
-mkLtExpr es = do {
-    (e1, e2) <- assertArgs2 "lt" es;
-    case e1 of
-    (AnyExpr _ (IntFunc _)) -> mkLtExpr' <$> assertInt e1 <*> assertInt e2
-    (AnyExpr _ (UintFunc _)) ->  mkLtExpr' <$> assertUint e1 <*> assertUint e2
-    (AnyExpr _ (DoubleFunc _)) -> mkLtExpr' <$> assertDouble e1 <*> assertDouble e2
-    (AnyExpr _ (BytesFunc _)) -> mkLtExpr' <$> assertBytes e1 <*> assertBytes e2
-}
-
-mkLtExpr' :: (Ord a) => Expr a -> Expr a -> AnyExpr
-mkLtExpr' e f = mkBoolExpr $ ltExpr e f
-
--- |
--- ltExpr creates a lt (less than) expression that returns true if the first evaluated expression is less than the second
--- and both don't evaluate to an error.
-ltExpr :: (Ord a) => Expr a -> Expr a -> Expr Bool
-ltExpr a b = trimBool Expr {
-    desc = mkDesc "lt" [desc a, desc b]
-    , eval = \v -> lt (eval a v) (eval b v)
-}
-
-lt :: (Ord a) => Either String a -> Either String a -> Either String Bool
-lt (Right v1) (Right v2) = return $ v1 < v2
-lt (Left _) _ = return False
-lt _ (Left _) = return False
diff --git a/src/Exprs/Contains.hs b/src/Exprs/Contains.hs
deleted file mode 100644
--- a/src/Exprs/Contains.hs
+++ /dev/null
@@ -1,48 +0,0 @@
--- |
--- This module contains the Relapse contains expressions.
-module Exprs.Contains (
-    mkContainsExpr
-    , containsStringExpr
-    , containsExpr
-) where
-
-import qualified Data.Text as Text
-
-import Expr
-
--- |
--- mkContainsExpr dynamically creates a contains expression, if the two input types are:
--- 
---     * String and String where the second string is the possible substring.
---     * A List of :Strings, Ints or Uints paired with a String, Int or Uint respectively.
-mkContainsExpr :: [AnyExpr] -> Either String AnyExpr
-mkContainsExpr es = do {
-    (e1, e2) <- assertArgs2 "contains" es;
-    case e2 of
-    (AnyExpr _ (StringFunc _)) -> mkContainsStringExpr' <$> assertString e1 <*> assertString e2
-    (AnyExpr _ (StringsFunc _)) -> mkContainsExpr' <$> assertString e1 <*> assertStrings e2
-    (AnyExpr _ (IntsFunc _)) -> mkContainsExpr' <$> assertInt e1 <*> assertInts e2
-    (AnyExpr _ (UintsFunc _)) -> mkContainsExpr' <$> assertUint e1 <*> assertUints e2
-}
-
-mkContainsStringExpr' :: Expr Text.Text -> Expr Text.Text -> AnyExpr
-mkContainsStringExpr' e f = mkBoolExpr $ containsStringExpr e f
-
--- |
--- containsStringExpr creates a contains expression that returns true if the second string is a substring of the first.
-containsStringExpr :: Expr Text.Text -> Expr Text.Text -> Expr Bool
-containsStringExpr s sub = trimBool Expr {
-    desc = mkDesc "contains" [desc s, desc sub]
-    , eval = \v -> Text.isInfixOf <$> eval sub v <*> eval s v
-}
-
-mkContainsExpr' :: (Eq a) => Expr a -> Expr [a] -> AnyExpr
-mkContainsExpr' e f = mkBoolExpr $ containsExpr e f
-
--- |
--- containsExpr creates a contains expression that returns true if the first argument is an element in the second list argument.
-containsExpr :: (Eq a) => Expr a -> Expr [a] -> Expr Bool
-containsExpr e es = trimBool Expr {
-    desc = mkDesc "contains" [desc e, desc es]
-    , eval = \v -> elem <$> eval e v <*> eval es v
-}
diff --git a/src/Exprs/Elem.hs b/src/Exprs/Elem.hs
deleted file mode 100644
--- a/src/Exprs/Elem.hs
+++ /dev/null
@@ -1,35 +0,0 @@
--- |
--- This module contains the Relapse elem expression.
-module Exprs.Elem (
-    mkElemExpr
-    , elemExpr
-) where
-
-import Expr
-
--- |
--- mkElemExpr dynamically creates an elem expression, if the first argument is a list and the second an int index.
-mkElemExpr :: [AnyExpr] -> Either String AnyExpr
-mkElemExpr es = do {
-    (e1, e2) <- assertArgs2 "elem" es;
-    case e1 of
-    (AnyExpr _ (BoolsFunc _)) -> mkElemExpr' mkBoolExpr <$> assertBools e1 <*> assertInt e2
-    (AnyExpr _ (IntsFunc _)) -> mkElemExpr' mkIntExpr <$> assertInts e1 <*> assertInt e2
-    (AnyExpr _ (UintsFunc _)) -> mkElemExpr' mkUintExpr <$> assertUints e1 <*> assertInt e2
-    (AnyExpr _ (DoublesFunc _)) -> mkElemExpr' mkDoubleExpr <$> assertDoubles e1 <*> assertInt e2
-    (AnyExpr _ (StringsFunc _)) -> mkElemExpr' mkStringExpr <$> assertStrings e1 <*> assertInt e2
-    (AnyExpr _ (ListOfBytesFunc _)) -> mkElemExpr' mkBytesExpr <$> assertListOfBytes e1 <*> assertInt e2
-}
-
-mkElemExpr' :: (Expr a -> AnyExpr) -> Expr [a] -> Expr Int -> AnyExpr
-mkElemExpr' mk list index =  mk $ elemExpr list index
-
--- | 
--- elemExpr creates an expression that returns an element from the list at the specified index.
--- Trimming this function would cause it to become non generic.
--- It is not necessary to trim each function, since it is just an optimization.
-elemExpr :: Expr [a] -> Expr Int -> Expr a
-elemExpr a b = Expr {
-    desc = mkDesc "elem" [desc a, desc b]
-    , eval = \v -> (!!) <$> eval a v <*> eval b v
-}
diff --git a/src/Exprs/Length.hs b/src/Exprs/Length.hs
deleted file mode 100644
--- a/src/Exprs/Length.hs
+++ /dev/null
@@ -1,54 +0,0 @@
--- |
--- This module contains the Relapse length expressions.
-module Exprs.Length (
-    mkLengthExpr
-    , lengthListExpr
-    , lengthStringExpr
-    , lengthBytesExpr
-) where
-
-import qualified Data.Text as Text
-import qualified Data.ByteString as ByteString
-
-import Expr
-
--- |
--- mkLengthExpr dynamically creates a length expression, if the single argument is a list, string or bytes.
-mkLengthExpr :: [AnyExpr] -> Either String AnyExpr
-mkLengthExpr es = do {
-    e <- assertArgs1 "length" es;
-    case e of
-    (AnyExpr _ (BoolsFunc _)) -> mkIntExpr . lengthListExpr <$> assertBools e;
-    (AnyExpr _ (IntsFunc _)) -> mkIntExpr . lengthListExpr <$> assertInts e;
-    (AnyExpr _ (UintsFunc _)) -> mkIntExpr . lengthListExpr <$> assertUints e;
-    (AnyExpr _ (DoublesFunc _)) -> mkIntExpr . lengthListExpr <$> assertDoubles e;
-    (AnyExpr _ (StringsFunc _)) -> mkIntExpr . lengthListExpr <$> assertStrings e;
-    (AnyExpr _ (ListOfBytesFunc _)) -> mkIntExpr . lengthListExpr <$> assertListOfBytes e;
-    (AnyExpr _ (StringFunc _)) -> mkIntExpr . lengthStringExpr <$> assertString e;
-    (AnyExpr _ (BytesFunc _)) -> mkIntExpr . lengthBytesExpr <$> assertBytes e;
-}
-
--- |
--- lengthListExpr creates a length expression, that returns the length of a list.
-lengthListExpr :: Expr [a] -> Expr Int
-lengthListExpr e = trimInt Expr {
-    desc = mkDesc "length" [desc e]
-    , eval = \v -> length <$> eval e v
-}
-
--- |
--- lengthStringExpr creates a length expression, that returns the length of a string.
-lengthStringExpr :: Expr Text.Text -> Expr Int
-lengthStringExpr e = trimInt Expr {
-    desc = mkDesc "length" [desc e]
-    , eval = \v -> Text.length <$> eval e v
-}
-
--- |
--- lengthBytesExpr creates a length expression, that returns the length of bytes.
-lengthBytesExpr :: Expr ByteString.ByteString -> Expr Int
-lengthBytesExpr e = trimInt Expr {
-    desc = mkDesc "length" [desc e]
-    , eval = \v -> ByteString.length <$> eval e v
-}
-
diff --git a/src/Exprs/Logic.hs b/src/Exprs/Logic.hs
deleted file mode 100644
--- a/src/Exprs/Logic.hs
+++ /dev/null
@@ -1,128 +0,0 @@
--- |
--- This module contains the Relapse logic expressions: not, and, or. 
-module Exprs.Logic (
-    mkNotExpr, notExpr
-    , mkAndExpr, andExpr
-    , mkOrExpr, orExpr
-) where
-
-import Expr
-import Exprs.Var
-
--- |
--- mkNotExpr dynamically creates a not expression, if the single argument is a bool expression.
-mkNotExpr :: [AnyExpr] -> Either String AnyExpr
-mkNotExpr es = do {
-    e <- assertArgs1 "not" es;
-    b <- assertBool e;
-    return $ mkBoolExpr (notExpr b);
-}
-
--- |
--- notExpr creates a not expression, that returns true is the argument expression returns an error or false.
-notExpr :: Expr Bool -> Expr Bool
-notExpr e = trimBool Expr {
-    desc = notDesc (desc e)
-    , eval = \v -> case eval e v of
-        (Left _) -> return True
-        (Right b) -> return $ not b
-}
-
--- notDesc superficially pushes not operators down to normalize functions.
--- Normalizing functions increases the chances of finding equal expressions and being able to simplify patterns.
-notDesc :: Desc -> Desc
-notDesc d
-    | _name d == "not" = 
-        let child0 = head $ _params d
-        in mkDesc (_name child0) (_params child0)
-    | _name d == "and" =
-        let [left, right] = _params d
-        in mkDesc "or" [mkDesc "not" [left], mkDesc "not" [right]]
-    | _name d == "or" =
-        let [left, right] = _params d
-        in mkDesc "and" [mkDesc "not" [left], mkDesc "not" [right]]
-    | _name d == "ne" = mkDesc "eq" $  _params d
-    | _name d == "eq" = mkDesc "ne" $ _params d
-    | otherwise = mkDesc "not" [d]
-
--- |
--- mkAndExpr dynamically creates an and expression, if the two arguments are both bool expressions.
-mkAndExpr :: [AnyExpr] -> Either String AnyExpr
-mkAndExpr es = do {
-    (e1, e2) <- assertArgs2 "and" es;
-    b1 <- assertBool e1;
-    b2 <- assertBool e2;
-    return $ mkBoolExpr $ andExpr b1 b2;
-}
-
--- |
--- andExpr creates an and expression that returns true if both arguments are true.
-andExpr :: Expr Bool -> Expr Bool -> Expr Bool
-andExpr a b = case (evalConst a, evalConst b) of
-    (Just False, _) -> boolExpr False
-    (_, Just False) -> boolExpr False
-    (Just True, _) -> b
-    (_, Just True) -> a
-    _ -> andExpr' a b
-
--- andExpr' creates an `and` expression, but assumes that both expressions have a var.
-andExpr' :: Expr Bool -> Expr Bool -> Expr Bool
-andExpr' a b
-    | a == b = a
-    | name a == "not" && head (params a) == desc b = boolExpr False
-    | name b == "not" && head (params b) == desc a = boolExpr False
-    | name a == "eq" && name b == "eq" = case (varAndConst a, varAndConst b) of
-        (Just ca, Just cb) -> if ca == cb then a else boolExpr False
-        _ -> defaultAnd a b
-    | name a == "eq" && name b == "ne" = case (varAndConst a, varAndConst b) of
-        (Just ca, Just cb) -> if ca == cb then boolExpr False else a
-        _ -> defaultAnd a b
-    | name a == "ne" && name b == "eq" = case (varAndConst a, varAndConst b) of
-        (Just ca, Just cb) -> if ca == cb then boolExpr False else b
-        _ -> defaultAnd a b
-    | otherwise = defaultAnd a b
-
-defaultAnd :: Expr Bool -> Expr Bool -> Expr Bool
-defaultAnd a b = Expr {
-    desc = mkDesc "and" [desc a, desc b]
-    , eval = \v -> (&&) <$> eval a v <*> eval b v
-}
-
-varAndConst :: Expr Bool -> Maybe Desc
-varAndConst e = let ps = params e
-    in if length ps /= 2 then Nothing
-    else let [a,b] = ps in
-        if isVar a && isConst b then Just b
-        else if isVar b && isConst a then Just a
-        else Nothing
-
--- |
--- mkOrExpr dynamically creates an or expression, if the two arguments are both bool expressions.
-mkOrExpr :: [AnyExpr] -> Either String AnyExpr
-mkOrExpr es = do {
-    (e1, e2) <- assertArgs2 "or" es;
-    b1 <- assertBool e1;
-    b2 <- assertBool e2;
-    return $ mkBoolExpr $ orExpr b1 b2;
-}
-
--- |
--- orExpr creates an or expression that returns true if either argument is true.
-orExpr :: Expr Bool -> Expr Bool -> Expr Bool
-orExpr a b = case (evalConst a, evalConst b) of
-    (Just True, _) -> boolExpr True
-    (_, Just True) -> boolExpr True
-    (Just False, _) -> b
-    (_, Just False) -> a
-    _ -> orExpr' a b
-
--- orExpr' creates an `or` expression, but assumes that both expressions have a var.
-orExpr' :: Expr Bool -> Expr Bool -> Expr Bool
-orExpr' a b
-    | a == b = a
-    | name a == "not" && head (params a) == desc b = boolExpr True
-    | name b == "not" && head (params b) == desc a = boolExpr True
-    | otherwise = Expr {
-        desc = mkDesc "or" [desc a, desc b]
-        , eval = \v -> (||) <$> eval a v <*> eval b v
-    }
diff --git a/src/Exprs/Strings.hs b/src/Exprs/Strings.hs
deleted file mode 100644
--- a/src/Exprs/Strings.hs
+++ /dev/null
@@ -1,107 +0,0 @@
--- |
--- This module contains the Relapse string expressions.
-
-module Exprs.Strings (
-    mkHasPrefixExpr, hasPrefixExpr
-    , mkHasSuffixExpr, hasSuffixExpr
-    , mkRegexExpr, regexExpr
-    , mkToLowerExpr, toLowerExpr
-    , mkToUpperExpr, toUpperExpr
-) where
-
-import Text.Regex.TDFA ((=~))
-import Data.Text (Text, isPrefixOf, isSuffixOf, toLower, toUpper, unpack)
-
-import Expr
-
--- |
--- mkHasPrefixExpr dynamically creates a hasPrefix expression.
-mkHasPrefixExpr :: [AnyExpr] -> Either String AnyExpr
-mkHasPrefixExpr es = do {
-    (e1, e2) <- assertArgs2 "hasPrefix" es;
-    s1 <- assertString e1;
-    s2 <- assertString e2;
-    return $ mkBoolExpr $ hasPrefixExpr s1 s2;
-}
-
--- |
--- hasPrefixExpr creates a hasPrefix expression that returns true if the second is a prefix of the first.
-hasPrefixExpr :: Expr Text -> Expr Text -> Expr Bool
-hasPrefixExpr e1 e2 = trimBool Expr {
-    desc = mkDesc "hasPrefix" [desc e1, desc e2]
-    , eval = \v -> isPrefixOf <$> eval e2 v <*> eval e1 v
-}
-
--- |
--- mkHasSuffixExpr dynamically creates a hasSuffix expression.
-mkHasSuffixExpr :: [AnyExpr] -> Either String AnyExpr
-mkHasSuffixExpr es = do {
-    (e1, e2) <- assertArgs2 "hasSuffix" es;
-    s1 <- assertString e1;
-    s2 <- assertString e2;
-    return $ mkBoolExpr $ hasSuffixExpr s1 s2;
-}
-
--- |
--- hasSuffixExpr creates a hasSuffix expression that returns true if the second is a suffix of the first.
-hasSuffixExpr :: Expr Text -> Expr Text -> Expr Bool
-hasSuffixExpr e1 e2 = trimBool Expr {
-    desc = mkDesc "hasSuffix" [desc e1, desc e2]
-    , eval = \v -> isSuffixOf <$> eval e2 v <*> eval e1 v
-}
-
--- |
--- mkRegexExpr dynamically creates a regex expression.
-mkRegexExpr :: [AnyExpr] -> Either String AnyExpr
-mkRegexExpr es = do {
-    (e1, e2) <- assertArgs2 "regex" es;
-    e <- assertString e1;
-    s <- assertString e2;
-    return $ mkBoolExpr $ regexExpr e s;
-}
-
--- |
--- regexExpr creates a regex expression that returns true if the first expression matches the second string. 
-regexExpr :: Expr Text -> Expr Text -> Expr Bool
-regexExpr e s = trimBool Expr {
-    desc = mkDesc "regex" [desc e, desc s]
-    , eval = \v -> do {
-        s1 <- eval s v;
-        e1 <- eval e v;
-        return $ (=~) (unpack s1) (unpack e1);
-    }
-}
-
--- |
--- mkToLowerExpr dynamically creates a toLower expression.
-mkToLowerExpr :: [AnyExpr] -> Either String AnyExpr
-mkToLowerExpr es = do {
-    e <- assertArgs1 "toLower" es;
-    s <- assertString e;
-    return $ mkStringExpr $ toLowerExpr s;
-}
-
--- |
--- toLowerExpr creates a toLower expression that converts the input string to a lowercase string.
-toLowerExpr :: Expr Text -> Expr Text
-toLowerExpr e = trimString Expr {
-    desc = mkDesc "toLower" [desc e]
-    , eval = \v -> toLower <$> eval e v
-}
-
--- |
--- mkToUpperExpr dynamically creates a toUpper expression.
-mkToUpperExpr :: [AnyExpr] -> Either String AnyExpr
-mkToUpperExpr es = do {
-    e <- assertArgs1 "toUpper" es;
-    s <- assertString e;
-    return $ mkStringExpr $ toUpperExpr s;
-}
-
--- |
--- toUpperExpr creates a toUpper expression that converts the input string to an uppercase string.
-toUpperExpr :: Expr Text -> Expr Text
-toUpperExpr e = trimString Expr {
-    desc = mkDesc "toUpper" [desc e]
-    , eval = \v -> toUpper <$> eval e v
-}
diff --git a/src/Exprs/Type.hs b/src/Exprs/Type.hs
deleted file mode 100644
--- a/src/Exprs/Type.hs
+++ /dev/null
@@ -1,36 +0,0 @@
--- |
--- This module contains the Relapse type expression.
-
-module Exprs.Type (
-    mkTypeExpr
-    , typeExpr
-) where
-
-import Expr
-
--- |
--- mkTypeExpr is used by the parser to create a type expression for the specific input type.
-mkTypeExpr :: [AnyExpr] -> Either String AnyExpr
-mkTypeExpr es = do {
-    e <- assertArgs1 "type" es; 
-    case e of
-    (AnyExpr _ (BoolFunc _)) -> mkBoolExpr . typeExpr <$> assertBool e;
-    (AnyExpr _ (IntFunc _)) -> mkBoolExpr . typeExpr <$> assertInt e;
-    (AnyExpr _ (UintFunc _)) -> mkBoolExpr . typeExpr <$> assertUint e;
-    (AnyExpr _ (DoubleFunc _)) -> mkBoolExpr . typeExpr <$> assertDouble e;
-    (AnyExpr _ (StringFunc _)) -> mkBoolExpr . typeExpr <$> assertString e;
-    (AnyExpr _ (BytesFunc _)) -> mkBoolExpr . typeExpr <$> assertBytes e;
-}
-
--- |
--- typeExpr creates an expression that returns true if the containing expression does not return an error.
--- For example: `(typeExpr varBoolExpr)` will ony return true is the field value is a bool.
-typeExpr :: Expr a -> Expr Bool
-typeExpr e = Expr {
-    desc = mkDesc "type" [desc e]
-    , eval = \v -> case eval e v of
-        (Left _) -> return False
-        (Right _) -> return True
-}
-
-
diff --git a/src/Exprs/Var.hs b/src/Exprs/Var.hs
deleted file mode 100644
--- a/src/Exprs/Var.hs
+++ /dev/null
@@ -1,126 +0,0 @@
--- |
--- This module contains all expressions for Relapse variables.
-
-module Exprs.Var (
-    varBoolExpr
-    , varIntExpr
-    , varUintExpr
-    , varDoubleExpr
-    , varStringExpr
-    , varBytesExpr
-    , isVar
-) where
-
-import Data.Text (Text)
-import Data.ByteString (ByteString)
-
-import qualified Parsers
-import Expr
-
--- |
--- isVar returns whether an expression is one of the six variable expressions.
-isVar :: Desc -> Bool
-isVar d = null (_params d) && case _name d of
-    "$bool" -> True
-    "$int" -> True
-    "$uint" -> True
-    "$double" -> True
-    "$string" -> True
-    "$[]byte" -> True
-    _ -> False
-
--- |
--- varBoolExpr creates a bool variable expression.
-varBoolExpr :: Expr Bool
-varBoolExpr = Expr {
-    desc = Desc {
-        _name = "$bool"
-        , _toStr = "$bool"
-        , _hash = hashWithName "$bool" []
-        , _params = []
-        , _hasVar = True
-    }
-    , eval = \l -> case l of
-        (Parsers.Bool b) -> Right b
-        _ -> Left "not a bool"
-}
-
--- |
--- varIntExpr creates an int variable expression.
-varIntExpr :: Expr Int
-varIntExpr = Expr {
-    desc = Desc {
-        _name = "$int"
-        , _toStr = "$int"
-        , _hash = hashWithName "$int" []
-        , _params = []
-        , _hasVar = True
-    }
-    , eval = \l -> case l of
-        (Parsers.Int i) -> Right i
-        _ -> Left "not an int"
-}
-
--- |
--- varUintExpr creates a uint variable expression.
-varUintExpr :: Expr Word
-varUintExpr = Expr {
-    desc = Desc {
-        _name = "$uint"
-        , _toStr = "$uint"
-        , _hash = hashWithName "$uint" []
-        , _params = []
-        , _hasVar = True
-    }
-    , eval = \l -> case l of
-        (Parsers.Uint u) -> Right u
-        _ -> Left "not a uint"
-}
-
--- |
--- varDoubleExpr creates a double variable expression.
-varDoubleExpr :: Expr Double
-varDoubleExpr = Expr {
-    desc = Desc {
-        _name = "$double"
-        , _toStr = "$double"
-        , _hash = hashWithName "$double" []
-        , _params = []
-        , _hasVar = True
-    }
-    , eval = \l -> case l of
-        (Parsers.Double d) -> Right d
-        _ -> Left "not a double"
-}
-
--- |
--- varStringExpr creates a string variable expression.
-varStringExpr :: Expr Text
-varStringExpr = Expr {
-    desc = Desc {
-        _name = "$string"
-        , _toStr = "$string"
-        , _hash = hashWithName "$string" []
-        , _params = []
-        , _hasVar = True
-    }
-    , eval = \l -> case l of
-        (Parsers.String s) -> Right s
-        _ -> Left "not a string"
-}
-
--- |
--- varBytesExpr creates a bytes variable expression.
-varBytesExpr :: Expr ByteString
-varBytesExpr = Expr {
-    desc = Desc {
-        _name = "$[]byte"
-        , _toStr = "$[]byte"
-        , _hash = hashWithName "$[]byte" []
-        , _params = []
-        , _hasVar = True
-    }
-    , eval = \l -> case l of
-        (Parsers.Bytes b) -> Right b
-        _ -> Left "not bytes"
-}
diff --git a/src/IfExprs.hs b/src/IfExprs.hs
deleted file mode 100644
--- a/src/IfExprs.hs
+++ /dev/null
@@ -1,85 +0,0 @@
--- |
--- This is an internal relapse module.
---
--- It contains multiple implementations of if expressions.
-
-module IfExprs (
-    IfExprs, IfExpr, newIfExpr,
-    evalIfExprs, compileIfExprs,
-    ZippedIfExprs, zipIfExprs, evalZippedIfExprs
-) where
-
-import Smart
-import Expr
-import Exprs.Logic
-import Simplify
-import Zip
-import Parsers
-
--- |
--- IfExpr contains a condition and a return pattern for each of the two cases.
-newtype IfExpr = IfExpr (Expr Bool, Pattern, Pattern)
-
--- |
--- newIfExpr creates an IfExpr.
-newIfExpr :: Expr Bool -> Pattern -> Pattern -> IfExpr
-newIfExpr c t e = IfExpr (c, t, e)
-
--- | IfExprs is a tree of if expressions, which contains a list of resulting patterns on each of its leaves.
-data IfExprs
-    = Cond {
-        cond :: Expr Bool
-        , thn :: IfExprs
-        , els :: IfExprs
-    }
-    | Ret [Pattern]
-
--- | compileIfExprs compiles a list of if expressions in an IfExprs tree, for efficient evaluation.
-compileIfExprs :: [IfExpr] -> IfExprs
-compileIfExprs [] = Ret []
-compileIfExprs (IfExpr ifExpr:es) = addIfExpr ifExpr (compileIfExprs es)
-
--- | valIfExprs evaluates a tree of if expressions and returns the resulting patterns or an error.
-evalIfExprs :: IfExprs -> Label -> Either String [Pattern]
-evalIfExprs (Ret ps) _ = return ps
-evalIfExprs (Cond c t e) l = do {
-    b <- eval c l;
-    if b then evalIfExprs t l else evalIfExprs e l
-}
-
-addIfExpr :: (Expr Bool, Pattern, Pattern) -> IfExprs -> IfExprs
-addIfExpr (c, t, e) (Ret ps) =
-    Cond c (Ret (t:ps)) (Ret (e:ps))
-addIfExpr (c, t, e) (Cond cs ts es)
-    | c == cs = Cond cs (addRet t ts) (addRet e es)
-    | boolExpr False == andExpr c cs = Cond cs (addRet e ts) (addIfExpr (c, t, e) es)
-    | boolExpr False == andExpr (notExpr c) cs = Cond cs (addIfExpr (c, t, e) ts) (addRet t es)
-    | otherwise = Cond cs (addIfExpr (c, t, e) ts) (addIfExpr (c, t, e) es)
-
-addRet :: Pattern -> IfExprs -> IfExprs
-addRet p (Ret ps) = Ret (p:ps)
-addRet p (Cond c t e) = Cond c (addRet p t) (addRet p e)
-
--- |
--- ZippedIfExprs is a tree of if expressions, but with a zipped pattern list and a zipper on each of the leaves.
-data ZippedIfExprs
-    = ZippedCond {
-        zcond :: Expr Bool
-        , zthn :: ZippedIfExprs
-        , zels :: ZippedIfExprs
-    }
-    | ZippedRet [Pattern] Zipper
-
--- | zipIfExprs compresses an if expression tree's leaves.
-zipIfExprs :: IfExprs -> ZippedIfExprs
-zipIfExprs (Cond c t e) = ZippedCond c (zipIfExprs t) (zipIfExprs e)
-zipIfExprs (Ret ps) = let (zps, zs) = zippy ps in ZippedRet zps zs
-
--- | evalZippedIfExprs evaulates a ZippedIfExprs tree and returns the zipped pattern list and zipper from the resulting leaf.
-evalZippedIfExprs :: ZippedIfExprs -> Label -> Either String ([Pattern], Zipper)
-evalZippedIfExprs (ZippedRet ps zs) _ = return (ps, zs)
-evalZippedIfExprs (ZippedCond c t e) v = do {
-    b <- eval c v;
-    if b then evalZippedIfExprs t v else evalZippedIfExprs e v
-}
-
diff --git a/src/Json.hs b/src/Json.hs
deleted file mode 100644
--- a/src/Json.hs
+++ /dev/null
@@ -1,50 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-
--- |
--- This module contains the Json Parser.
-
-module Json (
-    decodeJSON, JsonTree
-) where
-
-import Text.JSON (decode, Result(..), JSValue(..), fromJSString, fromJSObject)
-import Data.Ratio (denominator)
-import Data.Text (pack)
-
-import qualified Data.Tree as DataTree
-import Parsers
-
-instance Tree JsonTree where
-    getLabel (DataTree.Node l _) = l
-    getChildren (DataTree.Node _ cs) = cs
-
--- |
--- JsonTree is a tree that can be validated by Relapse.
-type JsonTree = DataTree.Tree Label
-
--- |
--- decodeJSON returns a JsonTree, given an input string.
-decodeJSON :: String -> Either String [JsonTree]
-decodeJSON s = case decode s of
-    (Error e) -> Left e
-    (Ok v) -> Right (uValue v)
-
-uValue :: JSValue -> [JsonTree]
-uValue JSNull = []
-uValue (JSBool b) = [DataTree.Node (Bool b) []]
-uValue (JSRational _ r) = if denominator r /= 1 
-    then [DataTree.Node (Double (fromRational r :: Double)) []]
-    else [DataTree.Node (Int $ truncate r) []]
-uValue (JSString s) = [DataTree.Node (String $ pack $ fromJSString s) []]
-uValue (JSArray vs) = uArray 0 vs
-uValue (JSObject o) = uObject $ fromJSObject o
-
-uArray :: Int -> [JSValue] -> [JsonTree]
-uArray _ [] = []
-uArray index (v:vs) = DataTree.Node (Int index) (uValue v):uArray (index+1) vs
-
-uObject :: [(String, JSValue)] -> [JsonTree]
-uObject = map uKeyValue
-
-uKeyValue :: (String, JSValue) -> JsonTree
-uKeyValue (name, value) = DataTree.Node (String $ pack name) (uValue value)
diff --git a/src/MemDerive.hs b/src/MemDerive.hs
deleted file mode 100644
--- a/src/MemDerive.hs
+++ /dev/null
@@ -1,90 +0,0 @@
--- |
--- This module is an efficient implementation of the derivative algorithm for trees.
---
--- It is intended to be used for production purposes.
---
--- This means that it gives up some readability for speed.
---
--- This module provides memoization of the nullable, calls and returns functions.
-
-module MemDerive (
-    derive, Mem, newMem, validate
-) where
-
-import qualified Data.Map.Strict as M
-import Control.Monad.State (State, runState, lift, state)
-import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
-
-import qualified Derive
-import Smart (Grammar, Pattern, lookupRef, nullable, lookupMain)
-import IfExprs
-import Expr
-import Zip
-import Parsers
-
-mem :: Ord k => (k -> v) -> k -> M.Map k v -> (v, M.Map k v)
-mem f k m
-    | M.member k m = (m M.! k, m)
-    | otherwise = let res = f k
-        in (res, M.insert k res m)
-
-type Calls = M.Map [Pattern] IfExprs
-type Returns = M.Map ([Pattern], [Bool]) [Pattern]
-
--- |
--- Mem is the object used to store memoized results of the nullable, calls and returns functions.
-newtype Mem = Mem (Calls, Returns)
-
--- |
--- newMem creates a object used for memoization by the validate function.
--- Each grammar should create its own memoize object.
-newMem :: Mem
-newMem = Mem (M.empty, M.empty)
-
-calls :: Grammar -> [Pattern] -> State Mem IfExprs
-calls g k = state $ \(Mem (c, r)) -> let (v', c') = mem (Derive.calls g) k c;
-    in (v', Mem (c', r))
-
-returns :: Grammar -> ([Pattern], [Bool]) -> State Mem [Pattern]
-returns g k = state $ \(Mem (c, r)) -> let (v', r') = mem (Derive.returns g) k r;
-    in (v', Mem (c, r'))
-
-mderive :: Tree t => Grammar -> [Pattern] -> [t] -> ExceptT String (State Mem) [Pattern]
-mderive _ ps [] = return ps
-mderive g ps (tree:ts) = do {
-    ifs <- lift $ calls g ps;
-    childps <- hoistExcept $ evalIfExprs ifs (getLabel tree);
-    (zchildps, zipper) <- return $ zippy childps;
-    childres <- mderive g zchildps (getChildren tree);
-    let 
-        nulls = map nullable childres
-        unzipns = unzipby zipper nulls
-    ;
-    rs <- lift $ returns g (ps, unzipns);
-    mderive g rs ts
-}
-
-hoistExcept :: (Monad m) => Either e a -> ExceptT e m a
-hoistExcept = ExceptT . return
-
--- |
--- derive is the classic derivative implementation for trees.
-derive :: Tree t => Grammar -> [t] -> Either String Pattern
-derive g ts =
-    let start = [lookupMain g]
-        (res, _) = runState (runExceptT $ mderive g start ts) newMem
-    in case res of
-        (Left l) -> Left l
-        (Right [r]) -> return r
-        (Right rs) -> Left $ "not a single pattern: " ++ show rs
-
--- |
--- validate is the uses the derivative implementation for trees and
--- return whether tree is valid, given the input grammar and start pattern.
-validate :: Tree t => Grammar -> Pattern -> [t] -> (State Mem) Bool
-validate g start tree = do {
-    rs <- runExceptT (mderive g [start] tree);
-    return $ case rs of
-        (Right [r]) -> nullable r
-        _ -> False
-}
diff --git a/src/Parser.hs b/src/Parser.hs
deleted file mode 100644
--- a/src/Parser.hs
+++ /dev/null
@@ -1,388 +0,0 @@
--- |
--- This module parses the Relapse Grammar using the Parsec Library.
-
-module Parser (
-    -- * Parse Grammar
-    parseGrammar, parseGrammarWithUDFs
-    -- * Internal functions
-    -- | These functions are exposed for testing purposes.
-    , grammar, pattern, nameExpr, expr, 
-    idLit, bytesCastLit, stringLit, doubleCastLit, uintCastLit, intLit, ws
-) where
-
-import Text.ParserCombinators.Parsec
-import Numeric (readDec, readOct, readHex, readFloat)
-import Data.Char (chr)
-import qualified Data.Text as Text
-import qualified Data.ByteString.Char8 as ByteString
-import Control.Arrow (left)
-
-import Expr
-import Exprs
-import Exprs.Logic
-import Exprs.Var
-import Ast
-
--- | parseGrammar parses the Relapse Grammar.
-parseGrammar :: String -> Either String Grammar
-parseGrammar = parseGrammarWithUDFs stdOnly
-
--- | parseGrammarWithUDFs parses the Relapse Grammar with extra user defined functions.
-parseGrammarWithUDFs :: MkFunc -> String -> Either String Grammar
-parseGrammarWithUDFs extraUDFs str = 
-    let mkFunc n es = case mkExpr n es of
-            (Left _) -> extraUDFs n es
-            (Right v) -> return v
-    in left show $ parse (grammar mkFunc <* eof) "" str
-
-infixl 4 <++>
-(<++>) :: CharParser () String -> CharParser () String -> CharParser () String
-f <++> g = (++) <$> f <*> g
-
-infixr 5 <::>
-(<::>) :: CharParser () Char -> CharParser () String -> CharParser () String
-f <::> g = (:) <$> f <*> g
-
-check :: Either String a -> CharParser () a
-check e = case e of
-    (Left err) -> fail err
-    (Right v) -> return v
-
-empty :: CharParser () String
-empty = return ""
-
-opt :: CharParser () Char -> CharParser () String
-opt p = (:"") <$> p <|> empty
-
-_lineComment :: CharParser () ()
-_lineComment = char '/' *> many (noneOf "\n") <* char '\n' *> return ()
-
-_blockComment :: CharParser () ()
-_blockComment = char '*' *> many (noneOf "*") <* char '*' <* char '/' *> return ()
-
-_comment :: CharParser () ()
-_comment = char '/' *> (_lineComment <|> _blockComment)
-
-_ws :: CharParser () ()
-_ws = _comment <|> () <$ space
-
--- | For internal testing
-ws :: CharParser () ()
-ws = () <$ many _ws
-
-bool :: CharParser () Bool
-bool = True <$ string "true"
-    <|> False <$ string "false"
-
-_decimalLit :: CharParser () Int
-_decimalLit = oneOf "123456789" <::> many digit >>= _read readDec
-
-_octalLit :: CharParser () Int
-_octalLit = many1 octDigit >>= _read readOct
-
-_hexLit :: CharParser () Int
-_hexLit = many1 hexDigit >>= _read readHex
-
-_read :: ReadS a -> String -> CharParser () a
-_read read s = case read s of
-    [(n, "")]   -> return n
-    ((n, ""):_) -> return n
-    _           -> fail "digit"
-
-_optionalSign :: (Num a) => CharParser () a
-_optionalSign = -1 <$ char '-' <|> return 1
-
-_signedIntLit :: CharParser () Int
-_signedIntLit = (*) <$> _optionalSign <*> _intLit
-
-_intLit :: CharParser () Int
-_intLit = _decimalLit 
-    <|> char '0' *> (_octalLit 
-                    <|> (oneOf "xX" *> _hexLit)
-                    <|> return 0
-    )
-
--- | For internal testing
-intLit :: CharParser () Int
-intLit = string "int(" *> _signedIntLit <* char ')'
-    <|> _signedIntLit
-    <?> "int_lit"
-
-uintLit :: CharParser () Word
-uintLit = do {
-    i <- intLit;
-    if i < 0
-        then fail "negative uint" 
-        else return $ fromIntegral i;
-}
-
--- | For internal testing
-uintCastLit :: CharParser () Word
-uintCastLit = string "uint(" *> uintLit <* char ')'
-
-_exponent :: CharParser () String
-_exponent = oneOf "eE" <::> (
-    oneOf "+-" <::> many1 digit 
-    <|> many1 digit)
-
-_floatLit :: CharParser () Double
-_floatLit = do
-    i <- many1 digit
-    e <- _exponent 
-        <|> ((string "." <|> empty) <++> 
-            (_exponent 
-            <|> many1 digit <++>
-                (_exponent
-                <|> empty)
-            )
-        ) 
-        <|> empty
-    _read readFloat (i ++ e)
-
--- | For internal testing
-doubleCastLit :: CharParser () Double
-doubleCastLit = string "double(" *> ((*) <$> _optionalSign <*> _floatLit) <* char ')'
-
--- | For internal testing
-idLit :: CharParser () String
-idLit = (letter <|> char '_') <::> many (alphaNum <|> char '_')
-
-_qualid :: CharParser () String
-_qualid = idLit <++> (concat <$> many (char '.' <::> idLit))
-
-_bigUValue :: CharParser () Char
-_bigUValue = char 'U' *> do {
-    hs <- count 8 hexDigit;
-    n <- _read readHex hs;
-    return $ toEnum n
-}
-
-_littleUValue :: CharParser () Char
-_littleUValue = char 'u' *> do { 
-    hs <- count 4 hexDigit;
-    n <- _read readHex hs;
-    return $ toEnum n
-}
-
-_escapedChar :: CharParser () Char
-_escapedChar = choice (zipWith (\c r -> r <$ char c) "abnfrtv'\\\"/" "\a\b\n\f\r\t\v\'\\\"/")
-
-_unicodeValue :: CharParser () Char
-_unicodeValue = (char '\\' *> 
-    (_bigUValue 
-        <|> _littleUValue 
-        <|> _hexByteUValue 
-        <|> _escapedChar
-        <|> _octalByteUValue)
-    ) <|> noneOf "\\\""
-
-_interpretedString :: CharParser () String
-_interpretedString = between (char '"') (char '"') (many _unicodeValue)
-
-_rawString :: CharParser () String
-_rawString = between (char '`') (char '`') (many $ noneOf "`")
-
--- | For internal testing
-stringLit :: CharParser () Text.Text
-stringLit = Text.pack <$> (_rawString <|> _interpretedString)
-
-_hexByteUValue :: CharParser () Char
-_hexByteUValue = char 'x' *> do {
-    hs <- count 2 hexDigit;
-    n <- _read readHex hs;
-    return $ chr n
-}
-
-_octalByteUValue :: CharParser () Char
-_octalByteUValue = do {
-    os <- count 3 octDigit;
-    n <- _read readOct os;
-    return $ toEnum n
-}
-
-_byteLit :: CharParser () Char
-_byteLit = do {
-    i <- _intLit;
-    if i > 255 then
-        fail $ "too large for byte: " ++ show i
-    else
-        return $ chr i
-}
-
-_byteElem :: CharParser () Char
-_byteElem = _byteLit <|> between (char '\'') (char '\'') (_unicodeValue <|> _octalByteUValue <|> _hexByteUValue)
-
--- | For internal testing
-bytesCastLit :: CharParser () ByteString.ByteString
-bytesCastLit = ByteString.pack <$> (string "[]byte{" *> sepBy (ws *> _byteElem <* ws) (char ',') <* char '}')
-
-_literal :: CharParser () AnyExpr
-_literal = mkBoolExpr . boolExpr <$> bool
-    <|> mkIntExpr . intExpr <$> intLit
-    <|> mkUintExpr . uintExpr <$> uintCastLit
-    <|> mkDoubleExpr . doubleExpr <$> doubleCastLit
-    <|> mkStringExpr . stringExpr <$> stringLit
-    <|> mkBytesExpr . bytesExpr <$> bytesCastLit
-
-_terminal :: CharParser () AnyExpr
-_terminal = (char '$' *> (
-    mkBoolExpr varBoolExpr <$ string "bool"
-    <|> mkIntExpr varIntExpr <$ string "int"
-    <|> mkUintExpr varUintExpr <$ string "uint"
-    <|> mkDoubleExpr varDoubleExpr <$ string "double"
-    <|> mkStringExpr varStringExpr <$ string "string"
-    <|> mkBytesExpr varBytesExpr <$ string "[]byte" ))
-    <|> _literal
-
-_builtinSymbol :: CharParser () String
-_builtinSymbol = string "==" 
-    <|> string "!=" 
-    <|> char '<' <::> opt (char '=')
-    <|> char '>' <::> opt (char '=')
-    <|> string "~="
-    <|> string "*="
-    <|> string "^="
-    <|> string "$="
-    <|> string "::"
-
-_builtin :: MkFunc -> CharParser () AnyExpr
-_builtin mkFunc = mkBuiltIn <$> _builtinSymbol <*> (ws *> _expr mkFunc) >>= check
-
-_function :: MkFunc -> CharParser () AnyExpr
-_function mkFunc = mkFunc <$> idLit <*> (char '(' *> sepBy (ws *> _expr mkFunc <* ws) (char ',') <* char ')') >>= check
-
-_listType :: CharParser () String
-_listType = char '[' <::> char ']' <::> (
-    string "bool"
-    <|> string "int"
-    <|> string "uint"
-    <|> string "double"
-    <|> string "string"
-    <|> string "[]byte" )
-
-_mustBool :: AnyExpr -> CharParser () (Expr Bool)
-_mustBool = check . assertBool
-
-newList :: String -> [AnyExpr] -> CharParser () AnyExpr
-newList "[]bool" es = mkBoolsExpr . boolsExpr <$> mapM (check . assertBool) es
-newList "[]int" es = mkIntsExpr . intsExpr <$> mapM (check . assertInt) es
-newList "[]uint" es = mkUintsExpr . uintsExpr <$> mapM (check . assertUint) es
-newList "[]double" es = mkDoublesExpr . doublesExpr <$> mapM (check . assertDouble) es
-newList "[]string" es = mkStringsExpr . stringsExpr <$> mapM (check . assertString) es
-newList "[][]byte" es = mkListOfBytesExpr . listOfBytesExpr <$> mapM (check . assertBytes) es
-
-_list :: MkFunc -> CharParser () AnyExpr
-_list mkFunc = do {
-    ltype <- _listType;
-    es <- ws *> char '{' *> sepBy (ws *> _expr mkFunc <* ws) (char ',') <* char '}';
-    newList ltype es
-}
-
-_expr :: MkFunc -> CharParser () AnyExpr
-_expr mkFunc = try _terminal <|> _list mkFunc <|> _function mkFunc
-
--- | For internal testing
-expr :: MkFunc -> CharParser () (Expr Bool)
-expr mkFunc = (try _terminal <|> _builtin mkFunc <|> _function mkFunc) >>= _mustBool
-
-_nameString :: CharParser () (Expr Bool)
-_nameString = (mkBuiltIn "==" <$> 
-    (_literal <|> 
-    (mkStringExpr . stringExpr . Text.pack <$> idLit))) 
-    >>= check >>= _mustBool
-
-sepBy2 :: CharParser () a -> String -> CharParser () [a]
-sepBy2 p sep = do {
-    x1 <- p;
-    string sep;
-    x2 <- p;
-    xs <- many (try (string sep *> p));
-    return (x1:x2:xs)
-}
-
-_nameChoice :: CharParser () (Expr Bool)
-_nameChoice = foldl1 orExpr <$> sepBy2 (ws *> nameExpr <* ws) "|"
-
--- | For internal testing
-nameExpr :: CharParser () (Expr Bool)
-nameExpr =  (boolExpr True <$ char '_')
-    <|> (notExpr <$> (char '!' *> ws *> char '(' *> ws *> nameExpr <* ws <* char ')'))
-    <|> (char '(' *> ws *> _nameChoice <* ws <* char ')')
-    <|> _nameString
-
-_concatPattern :: MkFunc -> CharParser () Pattern
-_concatPattern mkFunc = char '[' *> (foldl1 Concat <$> sepBy2 (ws *> pattern mkFunc <* ws) ",") <* optional (char ',' <* ws) <* char ']'
-
-_interleavePattern :: MkFunc -> CharParser () Pattern
-_interleavePattern mkFunc = char '{' *> (foldl1 Interleave <$> sepBy2 (ws *> pattern mkFunc <* ws) ";") <* optional (char ';' <* ws) <* char '}'
-
-_parenPattern :: MkFunc -> CharParser () Pattern
-_parenPattern mkFunc = do {
-    char '(';
-    ws;
-    first <- pattern mkFunc;
-    ws;
-    ( char ')' *> ws *>
-        (
-            ZeroOrMore first <$ char '*'
-            <|> Optional first <$ char '?'
-        )
-    ) <|> ( 
-        (
-            (first <$ char '|' >>= _orList mkFunc) <|> 
-            (first <$ char '&' >>= _andList mkFunc)
-        ) <* char ')'
-    )
-}
-
-_orList :: MkFunc -> Pattern -> CharParser () Pattern
-_orList mkFunc p = Or p . foldl1 Or <$> sepBy1 (ws *> pattern mkFunc <* ws) (char '|')
-
-_andList :: MkFunc -> Pattern -> CharParser () Pattern
-_andList mkFunc p = And p . foldl1 And <$> sepBy1 (ws *> pattern mkFunc <* ws) (char '&')
-
-_refPattern :: CharParser () Pattern
-_refPattern = Reference <$> (char '@' *> ws *> idLit)
-
-_notPattern :: MkFunc -> CharParser () Pattern
-_notPattern mkFunc = Not <$> (char '!' *> ws *> char '(' *> ws *> pattern mkFunc <* ws <* char ')')
-
-_emptyPattern :: CharParser () Pattern
-_emptyPattern = Empty <$ string "<empty>"
-
-_zanyPattern :: CharParser () Pattern
-_zanyPattern = ZAny <$ string "*"
-
-_containsPattern :: MkFunc -> CharParser () Pattern
-_containsPattern mkFunc = Contains <$> (char '.' *> pattern mkFunc)
-
-_treenodePattern :: MkFunc -> CharParser () Pattern
-_treenodePattern mkFunc = Node <$> nameExpr <*> ( ws *> ( try (char ':' *> ws *> pattern mkFunc) <|> _depthPattern mkFunc) )
-
-_depthPattern :: MkFunc -> CharParser () Pattern
-_depthPattern mkFunc = _concatPattern mkFunc <|> _interleavePattern mkFunc<|> _containsPattern mkFunc
-    <|> flip Node Empty <$> ( (string "->" *> expr mkFunc) <|> (_builtin mkFunc>>= _mustBool) )
-
-newContains :: CharParser () AnyExpr -> CharParser () Pattern
-newContains e = flip Node Empty <$> ((mkBuiltIn "*=" <$> e) >>= check >>= _mustBool)
-
--- | For internal testing
-pattern :: MkFunc -> CharParser () Pattern
-pattern mkFunc = char '*' *> (
-        (char '=' *> newContains (ws *> _expr mkFunc))
-        <|> return ZAny
-    ) <|> _parenPattern mkFunc
-    <|> _refPattern
-    <|> try _emptyPattern
-    <|> try (_treenodePattern mkFunc)
-    <|> try (_depthPattern mkFunc)
-    <|> _notPattern mkFunc
-    
-_patternDecl :: MkFunc -> CharParser () Grammar
-_patternDecl mkFunc = newRef <$> (char '#' *> ws *> idLit) <*> (ws *> char '=' *> ws *> pattern mkFunc)
-
--- | For internal testing
-grammar :: MkFunc -> CharParser () Grammar
-grammar mkFunc = ws *> (foldl1 union <$> many1 (_patternDecl mkFunc <* ws))
-    <|> union <$> (newRef "main" <$> pattern mkFunc) <*> (foldl union emptyRef <$> many (ws *> _patternDecl mkFunc <* ws))
-
diff --git a/src/Parsers.hs b/src/Parsers.hs
deleted file mode 100644
--- a/src/Parsers.hs
+++ /dev/null
@@ -1,34 +0,0 @@
-{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
-
--- |
--- This module describes the abstract tree that can be validated by Relapse.
---
--- The JSON and XML parsers both are both versions of this type class.
-
-module Parsers (
-    Tree(..), Label(..)
-) where
-
-import Control.DeepSeq (NFData)
-import GHC.Generics (Generic)
-import Data.Text (Text)
-import Data.ByteString (ByteString)
-
--- |
--- Label is a tagged union of all possible value types that can returned by a katydid parser: 
--- String, Int, Uint, Double, Bool and Bytes.
-data Label
-    = String Text
-    | Int Int
-    | Uint Word
-    | Double Double
-    | Bool Bool
-    | Bytes ByteString
-    deriving (Show, Eq, Ord, Generic, NFData)
-
--- |
--- Tree is the type class that should be implemented by a katydid parser.
--- This is implemented by the Json and XML parser.
-class Tree a where
-    getLabel :: a -> Label
-    getChildren :: a -> [a]
diff --git a/src/Relapse.hs b/src/Relapse.hs
deleted file mode 100644
--- a/src/Relapse.hs
+++ /dev/null
@@ -1,66 +0,0 @@
--- |
--- This module provides an implementation of the relapse validation language.
---
--- Relapse is intended to be used for validation of trees or filtering of lists of trees.
---
--- Katydid currently provides two types of trees out of the box: Json and XML, 
--- but relapse supports any type of tree as long the type 
--- is of the Tree typeclass provided by the Parsers module.
---
--- The validate and filter functions expects a Tree to be a list of trees, 
--- since not all serialization formats have a single root.
--- For example, valid json like "[1, 2]" does not have a single root.
--- Relapse can also validate these types of trees.  
--- If your tree has a single root, simply provide a singleton list as input.
-
-module Relapse (
-    parse, parseWithUDFs, Grammar
-    , validate, filter
-) where
-
-import Prelude hiding (filter)
-import Control.Monad.State (runState)
-import Control.Monad (filterM)
-
-import qualified Parser
-import qualified Ast
-import qualified MemDerive
-import qualified Smart
-import Parsers
-import qualified Exprs
-
--- | Grammar represents a compiled relapse grammar.
-newtype Grammar = Grammar Smart.Grammar
-
--- |
--- parse parses the relapse grammar and returns either a parsed grammar or an error string.
-parse :: String -> Either String Grammar
-parse grammarString = do {
-    parsed <- Parser.parseGrammar grammarString;
-    Grammar <$> Smart.compile parsed;
-}
-
--- |
--- parseWithUDFs parses the relapse grammar with extra user defined functions
--- and returns either a parsed grammar or an error string.
-parseWithUDFs :: Exprs.MkFunc -> String -> Either String Grammar
-parseWithUDFs userLib grammarString = do {
-    parsed <- Parser.parseGrammarWithUDFs userLib grammarString;
-    Grammar <$> Smart.compile parsed;
-}
-
--- |
--- validate returns whether a tree is valid, given the grammar.
-validate :: Tree t => Grammar -> [t] -> Bool
-validate g tree = case filter g [tree] of
-    [] -> False
-    _ -> True
-
--- |
--- filter returns a filtered list of trees, given the grammar.
-filter :: Tree t => Grammar -> [[t]] -> [[t]]
-filter (Grammar g) trees = 
-    let start = Smart.lookupMain g
-        f = filterM (MemDerive.validate g start) trees
-        (r, _) = runState f MemDerive.newMem
-    in r
diff --git a/src/Simplify.hs b/src/Simplify.hs
deleted file mode 100644
--- a/src/Simplify.hs
+++ /dev/null
@@ -1,136 +0,0 @@
-{-#LANGUAGE GADTs #-}
-
--- |
--- This module simplifies Relapse patterns.
-
-module Simplify (
-    simplify  
-) where
-
-import qualified Data.Set as S
-
-import Ast
-import Expr
-import Exprs.Logic
-
--- |
--- simplify simplifies an input pattern to an equivalent simpler pattern.
-simplify :: Grammar -> Pattern -> Pattern
-simplify g pat =
-    let simp = simplify' g
-    in case pat of
-    Empty -> Empty
-    ZAny -> ZAny
-    (Node v p) -> simplifyNode v (simp p)
-    (Concat p1 p2) -> simplifyConcat (simp p1) (simp p2)
-    (Or p1 p2) -> simplifyOr g (simp p1) (simp p2)
-    (And p1 p2) -> simplifyAnd g (simp p1) (simp p2)
-    (ZeroOrMore p) -> simplifyZeroOrMore (simp p)
-    (Not p) -> simplifyNot (simp p)
-    (Optional p) -> simplifyOptional (simp p)
-    (Interleave p1 p2) -> simplifyInterleave (simp p1) (simp p2)
-    (Contains p) -> simplifyContains (simp p)
-    p@(Reference _) -> p
-
-simplify' :: Grammar -> Pattern -> Pattern
-simplify' g p = checkRef g $ simplify g p
-
-simplifyNode :: Expr Bool -> Pattern -> Pattern
-simplifyNode v p = case evalConst v of
-    (Just False) -> Not ZAny
-    _ -> Node v p
-
-simplifyConcat :: Pattern -> Pattern -> Pattern
-simplifyConcat (Not ZAny) _ = Not ZAny
-simplifyConcat _ (Not ZAny) = Not ZAny
-simplifyConcat (Concat p1 p2) p3 = 
-    simplifyConcat p1 (Concat p2 p3)
-simplifyConcat Empty p = p
-simplifyConcat p Empty = p
-simplifyConcat ZAny (Concat p ZAny) = Contains p
-simplifyConcat p1 p2 = Concat p1 p2
-
-simplifyOr :: Grammar -> Pattern -> Pattern -> Pattern
-simplifyOr _ (Not ZAny) p = p
-simplifyOr _ p (Not ZAny) = p
-simplifyOr _ ZAny _ = ZAny
-simplifyOr _ _ ZAny = ZAny
-simplifyOr _ (Node v1 Empty) (Node v2 Empty) = Node (orExpr v1 v2) Empty
-simplifyOr g Empty p 
-    | nullable g p == Right True = p
-    | otherwise = Or Empty p
-simplifyOr g p Empty
-    | nullable g p == Right True = p 
-    | otherwise = Or Empty p
-simplifyOr _ p1 p2 = bin Or $ simplifyChildren Or $ S.toAscList $ setOfOrs p1 `S.union` setOfOrs p2
-
-simplifyChildren :: (Pattern -> Pattern -> Pattern) -> [Pattern] -> [Pattern]
-simplifyChildren _ [] = []
-simplifyChildren _ [p] = [p]
-simplifyChildren op (p1@(Node v1 c1):(p2@(Node v2 c2):ps))
-    | v1 == v2 = simplifyChildren op $ Node v1 (op c1 c2):ps
-    | otherwise = p1:simplifyChildren op (p2:ps)
-simplifyChildren op (p:ps) = p:simplifyChildren op ps
-
-bin :: (Pattern -> Pattern -> Pattern) -> [Pattern] -> Pattern
-bin op [p] = p
-bin op [p1,p2] = op p1 p2
-bin op (p:ps) = op p (bin op ps)
-
-setOfOrs :: Pattern -> S.Set Pattern
-setOfOrs (Or p1 p2) = setOfOrs p1 `S.union` setOfOrs p2
-setOfOrs p = S.singleton p
-
-simplifyAnd :: Grammar -> Pattern -> Pattern -> Pattern
-simplifyAnd _ (Not ZAny) _ = Not ZAny
-simplifyAnd _ _ (Not ZAny) = Not ZAny
-simplifyAnd _ ZAny p = p
-simplifyAnd _ p ZAny = p
-simplifyAnd _ (Node v1 Empty) (Node v2 Empty) = Node (andExpr v1 v2) Empty
-simplifyAnd g Empty p
-    | nullable g p == Right True = Empty
-    | otherwise = Not ZAny
-simplifyAnd g p Empty
-    | nullable g p == Right True = Empty
-    | otherwise = Not ZAny
-simplifyAnd _ p1 p2 = bin And $ simplifyChildren And $ S.toAscList $ setOfAnds p1 `S.union` setOfAnds p2
-
-setOfAnds :: Pattern -> S.Set Pattern
-setOfAnds (And p1 p2) = setOfAnds p1 `S.union` setOfAnds p2
-setOfAnds p = S.singleton p
-
-simplifyZeroOrMore :: Pattern -> Pattern
-simplifyZeroOrMore (ZeroOrMore p) = ZeroOrMore p
-simplifyZeroOrMore p = ZeroOrMore p
-
-simplifyNot :: Pattern -> Pattern
-simplifyNot (Not p) = p
-simplifyNot p = Not p
-
-simplifyOptional :: Pattern -> Pattern
-simplifyOptional Empty = Empty
-simplifyOptional p = Optional p
-
-simplifyInterleave :: Pattern -> Pattern -> Pattern
-simplifyInterleave (Not ZAny) _ = Not ZAny
-simplifyInterleave _ (Not ZAny) = Not ZAny
-simplifyInterleave Empty p = p
-simplifyInterleave p Empty = p
-simplifyInterleave ZAny ZAny = ZAny
-simplifyInterleave p1 p2 = bin Interleave $ S.toAscList $ setOfInterleaves p1 `S.union` setOfInterleaves p2
-
-setOfInterleaves :: Pattern -> S.Set Pattern
-setOfInterleaves (Interleave p1 p2) = setOfInterleaves p1 `S.union` setOfInterleaves p2
-setOfInterleaves p = S.singleton p
-
-simplifyContains :: Pattern -> Pattern
-simplifyContains Empty = ZAny
-simplifyContains ZAny = ZAny
-simplifyContains (Not ZAny) = Not ZAny
-simplifyContains p = Contains p
-
-checkRef :: Grammar -> Pattern -> Pattern
-checkRef g p = case reverseLookupRef p g of
-    Nothing     -> p
-    (Just k)    -> Reference k
-
diff --git a/src/Smart.hs b/src/Smart.hs
deleted file mode 100644
--- a/src/Smart.hs
+++ /dev/null
@@ -1,417 +0,0 @@
--- |
--- This module describes the smart constructors for Relapse patterns.
-module Smart (
-    Pattern(..)
-    , Grammar
-    , lookupRef
-    , compile
-    , emptyPat, zanyPat, nodePat
-    , orPat, andPat, notPat 
-    , concatPat, interleavePat
-    , zeroOrMorePat, optionalPat
-    , containsPat, refPat
-    , emptySet
-    , unescapable
-    , nullable
-    , lookupMain
-) where
-
-import qualified Data.Map.Strict as M
-import qualified Data.Set as S
-import Data.List (sort, sortBy, intercalate)
-import Control.Monad (when)
-
-import qualified Expr
-import Exprs.Logic (orExpr, andExpr)
-import qualified Ast
-
--- | compile complies an ast into a smart grammar.
-compile :: Ast.Grammar -> Either String Grammar
-compile g = do {
-    Ast.lookupRef g "main"; -- making sure that the main reference exists.
-    hasRec <- Ast.hasRecursion g;
-    when hasRec $ Left "recursion without interleaved treenode not supported";
-    refs <- M.fromList <$> mapM (\name -> do {
-        p <- Ast.lookupRef g name;
-        return (name, p)
-    }) (Ast.listRefs g);
-    nullRefs <- mapM (Ast.nullable g) refs;
-    Grammar <$> mapM (smart nullRefs) refs
-}
-
-smart :: M.Map String Bool -> Ast.Pattern -> Either String Pattern
-smart _ Ast.Empty = return emptyPat
-smart nulls (Ast.Node e p) = nodePat e <$> smart nulls p
-smart nulls (Ast.Concat a b) = concatPat <$> smart nulls a <*> smart nulls b
-smart nulls (Ast.Or a b) = orPat <$> smart nulls a <*> smart nulls b
-smart nulls (Ast.And a b) = andPat <$> smart nulls a <*> smart nulls b
-smart nulls (Ast.ZeroOrMore p) = zeroOrMorePat <$> smart nulls p
-smart nulls (Ast.Reference name) = refPat nulls name
-smart nulls (Ast.Not p) = notPat <$> smart nulls p
-smart _ Ast.ZAny = return zanyPat
-smart nulls (Ast.Contains p) = containsPat <$> smart nulls p
-smart nulls (Ast.Optional p) = optionalPat <$> smart nulls p
-smart nulls (Ast.Interleave a b) = interleavePat <$> smart nulls a <*> smart nulls b
-
--- |
--- Pattern recursively describes a Relapse Pattern.
-data Pattern = Empty
-    | Node {
-        expr :: Expr.Expr Bool
-        , pat :: Pattern
-        , _hash :: Int
-    }
-    | Concat {
-        left :: Pattern
-        , right :: Pattern
-        , _nullable :: Bool
-        , _hash :: Int
-    }
-    | Or {
-        pats :: [Pattern]
-        , _nullable :: Bool
-        , _hash :: Int
-    }
-    | And {
-        pats :: [Pattern]
-        , _nullable :: Bool
-        , _hash :: Int
-    }
-    | ZeroOrMore {
-        pat :: Pattern
-        , _hash :: Int
-    }
-    | Reference {
-        refName :: ValidRef
-        , _nullable :: Bool
-        , _hash :: Int
-    }
-    | Not {
-        pat :: Pattern
-        , _nullable :: Bool
-        , _hash :: Int
-    }
-    | ZAny
-    | Contains {
-        pat :: Pattern
-        , _nullable :: Bool
-        , _hash :: Int
-    }
-    | Optional {
-        pat :: Pattern
-        , _hash :: Int
-    }
-    | Interleave {
-        pats :: [Pattern]
-        , _nullable :: Bool
-        , _hash :: Int
-    }
-    deriving (Eq, Ord)
-
-instance Show Pattern where
-    show = toStr
-
-toStr :: Pattern -> String
-toStr Empty = "<empty>"
-toStr Node{expr=e, pat=p} = show e ++ ":" ++ show p
-toStr Concat{left=l,right=r} = "[" ++ show l ++ "," ++ show r ++ "]"
-toStr Or{pats=ps} = "(" ++ intercalate "|" (map show ps) ++ ")"
-toStr And{pats=ps} = "(" ++ intercalate "&" (map show ps) ++ ")"
-toStr ZeroOrMore{pat=p} = "(" ++ show p ++ ")*"
-toStr Reference{refName=(ValidRef n)} = "@"++n
-toStr Not{pat=p} = "!(" ++ show p ++ ")"
-toStr ZAny = "*"
-toStr Contains{pat=p} = "." ++ show p
-toStr Optional{pat=p} = "(" ++ show p ++ ")?"
-toStr Interleave{pats=ps} = "{" ++ intercalate ";" (map show ps) ++ "}"
-
--- cmp is an efficient comparison function for patterns.
--- It is very important that cmp is efficient, 
--- because it is a bottleneck for simplification and smart construction of large queries.
-cmp :: Pattern -> Pattern -> Ordering
-cmp a b = if hashcmp == EQ then compare a b else hashcmp
-    where hashcmp = compare (hash a) (hash b)
-
--- eq is an efficient comparison function for patterns.
--- It is very important that eq is efficient, 
--- because it is a bottleneck for simplification and smart construction of large queries.
-eq :: Pattern -> Pattern -> Bool
-eq a b = cmp a b == EQ
-
-hash :: Pattern -> Int
-hash Empty = 3
-hash Node{_hash=h} = h
-hash Concat{_hash=h} = h
-hash Or{_hash=h} = h
-hash And{_hash=h} = h
-hash ZeroOrMore{_hash=h} = h
-hash Reference{_hash=h} = h
-hash Not{_hash=h} = h
-hash ZAny = 5
-hash Contains{_hash=h} = h
-hash Optional{_hash=h} = h
-hash Interleave{_hash=h} = h
-
--- | nullable returns whether the pattern matches the empty string.
-nullable :: Pattern -> Bool
-nullable Empty = True
-nullable Node{} = False
-nullable Concat{_nullable=n} = n
-nullable Or{_nullable=n} = n
-nullable And{_nullable=n} = n
-nullable ZeroOrMore{} = True
-nullable Reference{_nullable=n} = n
-nullable Not{_nullable=n} = n
-nullable ZAny = True
-nullable Contains{_nullable=n} = n
-nullable Optional{} = True
-nullable Interleave{_nullable=n} = n
-
--- | emptyPat is the smart constructor for the empty pattern.
-emptyPat :: Pattern
-emptyPat = Empty
-
--- | zanyPat is the smart constructor for the zany pattern.
-zanyPat :: Pattern
-zanyPat = ZAny
-
--- | notPat is the smart constructor for the not pattern.
-notPat :: Pattern -> Pattern
-notPat Not {pat=p} = p
-notPat p = Not {
-    pat = p
-    , _nullable = not $ nullable p
-    , _hash = 31 * 7 + hash p
-}
-
--- | emptySet is the smart constructor for the !(*) pattern.
-emptySet :: Pattern
-emptySet = notPat zanyPat
-
--- | nodePat is the smart constructor for the node pattern.
-nodePat :: Expr.Expr Bool -> Pattern -> Pattern
-nodePat e p =
-    case Expr.evalConst e of
-    (Just False) -> emptySet
-    _ -> Node {
-        expr = e
-        , pat = p
-        , _hash = 31 * (11 + 31 * Expr._hash (Expr.desc e)) + hash p
-    }
-
-isLeaf :: Pattern -> Bool
-isLeaf Node{pat=Empty} = True
-isLeaf _ = False
-
--- | concatPat is the smart constructor for the concat pattern.
-concatPat :: Pattern -> Pattern -> Pattern
-concatPat notZAny@Not{pat=ZAny} _ = notZAny
-concatPat _ notZAny@Not{pat=ZAny} = notZAny
-concatPat Empty b = b
-concatPat a Empty = a
-concatPat Concat{left=a1, right=a2} b = concatPat a1 (concatPat a2 b)
-concatPat ZAny Concat{left=b1, right=ZAny} = containsPat b1
-concatPat a b = Concat {
-    left = a
-    , right = b 
-    , _nullable = nullable a && nullable b
-    , _hash = 31 * (13 + 31 * hash a) + hash b
-}
-
--- | containsPat is the smart constructor for the contains pattern.
-containsPat :: Pattern -> Pattern
-containsPat Empty = ZAny
-containsPat p@ZAny = p
-containsPat p@Not{pat=ZAny} = p
-containsPat p = Contains {
-    pat = p
-    , _nullable = nullable p
-    , _hash = 31 * 17 + hash p
-}
-
--- | optionalPat is the smart constructor for the optional pattern.
-optionalPat :: Pattern -> Pattern
-optionalPat p@Empty = p
-optionalPat p@Optional{} = p
-optionalPat p = Optional {
-    pat = p
-    , _hash = 31 * 19 + hash p
-}
-
--- | zeroOrMorePat is the smart constructor for the zeroOrMore pattern.
-zeroOrMorePat :: Pattern -> Pattern
-zeroOrMorePat p@ZeroOrMore{} = p
-zeroOrMorePat p = ZeroOrMore {
-    pat = p
-    , _hash = 31 * 23 + hash p
-}
-
--- | refPat is the smart constructor for the reference pattern.
-refPat :: M.Map String Bool -> String -> Either String Pattern
-refPat nullRefs name = 
-    case M.lookup name nullRefs of
-        Nothing -> Left $ "no reference named: " ++ name
-        (Just n) -> Right Reference {
-            refName = ValidRef name
-            , _hash = 31 * 29 + Expr.hashString name
-            , _nullable = n
-        }
-
--- | orPat is the smart constructor for the or pattern.
-orPat :: Pattern -> Pattern -> Pattern
-orPat a b = orPat' $ S.fromList (getOrs a ++ getOrs b)
-
-getOrs :: Pattern -> [Pattern]
-getOrs Or{pats=ps} = ps
-getOrs p = [p]
-
-orPat' :: S.Set Pattern -> Pattern
-orPat' ps = ps `returnIfSingleton`
-    \ps -> if S.member zanyPat ps
-        then zanyPat
-        else S.delete emptySet ps `returnIfSingleton`
-    \ps -> (if all nullable ps
-        then S.delete emptyPat ps
-        else ps) `returnIfSingleton`
-    \ps -> mergeLeaves orExpr ps `returnIfSingleton`
-    \ps -> mergeNodesWithEqualNames orPat ps `returnIfSingleton`
-    \ps -> let psList = sort $ S.toList ps
-    in  Or {
-            pats = psList
-            , _nullable = any nullable psList
-            , _hash = Expr.hashList (31*33) $ map hash psList
-        }
-
--- | andPat is the smart constructor for the and pattern.
-andPat :: Pattern -> Pattern -> Pattern
-andPat a b = andPat' $ S.fromList (getAnds a ++ getAnds b)
-
-getAnds :: Pattern -> [Pattern]
-getAnds And{pats=ps} = ps
-getAnds p = [p]
-
-andPat' :: S.Set Pattern -> Pattern
-andPat' ps = ps `returnIfSingleton`
-    \ps -> if S.member emptySet ps
-        then emptySet
-        else S.delete zanyPat ps `returnIfSingleton`
-    \ps -> if S.member emptyPat ps
-        then if all nullable ps
-            then emptyPat
-            else emptySet 
-        else ps `returnIfSingleton`
-    \ps -> mergeLeaves andExpr ps `returnIfSingleton`
-    \ps -> mergeNodesWithEqualNames andPat ps `returnIfSingleton`
-    \ps -> let psList = sort $ S.toList ps 
-    in And {
-        pats = psList
-        , _nullable = all nullable psList
-        , _hash = Expr.hashList (31*37) $ map hash psList
-    }
-
--- | returnIfSingleton returns the pattern from the set if the set is of size one, otherwise it applies the function to the set.
-returnIfSingleton :: S.Set Pattern -> (S.Set Pattern -> Pattern) -> Pattern
-returnIfSingleton s1 f =
-    if S.size s1 == 1 then head $ S.toList s1 else f s1
-
-mergeLeaves :: (Expr.Expr Bool -> Expr.Expr Bool -> Expr.Expr Bool) -> S.Set Pattern -> S.Set Pattern
-mergeLeaves merger = merge $ \a b -> case (a,b) of
-    (Node{expr=ea,pat=Empty},Node{expr=eb,pat=Empty}) -> [nodePat (merger ea eb) emptyPat]
-    _ -> [a,b]
-
-mergeNodesWithEqualNames :: (Pattern -> Pattern -> Pattern) -> S.Set Pattern -> S.Set Pattern
-mergeNodesWithEqualNames merger = merge $ \a b -> case (a,b) of
-    (Node{expr=ea,pat=pa},Node{expr=eb,pat=pb}) -> 
-        if ea == eb then [nodePat ea (merger pa pb)] else [a,b]
-    _ -> [a,b]
-
-merge :: (Pattern -> Pattern -> [Pattern]) -> S.Set Pattern -> S.Set Pattern
-merge merger ps = let list = sortBy leavesThenNamesAndThenContains (S.toList ps)
-    in S.fromList $ foldl (\(a:merged) b -> merger a b ++ merged) [head list] (tail list)
-
-leavesThenNamesAndThenContains :: Pattern -> Pattern -> Ordering
-leavesThenNamesAndThenContains a@Node{} b@Node{} = leavesFirst a b
-leavesThenNamesAndThenContains Node{} _ = LT
-leavesThenNamesAndThenContains _ Node{} = GT
-leavesThenNamesAndThenContains a b = containsThird a b
-
-leavesFirst :: Pattern -> Pattern -> Ordering
-leavesFirst a b
-    | isLeaf a && isLeaf b = compare a b
-    | isLeaf a = LT
-    | isLeaf b = GT
-    | otherwise = namesSecond a b
-
-namesSecond :: Pattern -> Pattern -> Ordering
-namesSecond a@Node{expr=ea} b@Node{expr=eb} = let fcomp = compare ea eb
-    in if fcomp == EQ 
-        then compare a b
-        else fcomp
-
-containsThird :: Pattern -> Pattern -> Ordering
-containsThird a@Contains{} b@Contains{} = compare a b
-containsThird Contains{} _ = LT
-containsThird _ Contains{} = GT
-containsThird a b = compare a b
-
--- | interleavePat is the smart constructor for the interleave pattern.
-interleavePat :: Pattern -> Pattern -> Pattern
-interleavePat a b = interleavePat' (getInterleaves a ++ getInterleaves b)
-
-getInterleaves :: Pattern -> [Pattern]
-getInterleaves Interleave{pats=ps} = ps
-getInterleaves p = [p]
-
-interleavePat' :: [Pattern] -> Pattern
-interleavePat' ps
-    | emptySet `elem` ps = emptySet
-    | all (eq Empty) ps = emptyPat
-    | otherwise = delete Empty ps `returnIfOnlyOne`
-        \ps -> (if any (eq ZAny) ps
-            then zanyPat : delete ZAny ps
-            else ps) `returnIfOnlyOne`
-        \ps -> let psList = sort ps
-        in Interleave {
-            pats = psList
-            , _nullable = all nullable psList
-            , _hash = Expr.hashList (31*41) $ map hash psList
-        }
-
--- | returnIfOnlyOne returns the pattern from the list if the list is of size one, otherwise it applies the function to the list.
-returnIfOnlyOne :: [Pattern] -> ([Pattern] -> Pattern) -> Pattern
-returnIfOnlyOne xs f = if length xs == 1 then head xs else f xs
-
-delete :: Pattern -> [Pattern] -> [Pattern]
-delete removeItem = filter (not . (\p -> p == removeItem))
-
--- |
--- unescapable is used for short circuiting.
--- A part of the tree can be skipped if all patterns are unescapable.
-unescapable :: Pattern -> Bool
-unescapable ZAny = True
-unescapable Not{pat=ZAny} = True
-unescapable _ = False
-
--- |
--- Grammar is a map from reference name to pattern and describes a relapse grammar.
-newtype Grammar = Grammar Refs
-    deriving (Show, Eq)
-
--- |
--- Refs is a map from reference name to pattern, excluding the main reference, which makes a relapse grammar.
-type Refs = M.Map String Pattern
-
-newtype ValidRef = ValidRef String
-    deriving (Eq, Ord, Show)
-
--- |
--- lookupRef looks up a pattern in the reference map, given a reference name.
-lookupRef :: Grammar -> ValidRef -> Pattern
-lookupRef (Grammar refs) (ValidRef name) = 
-    case M.lookup name refs of
-        Nothing -> error $ "valid reference not found: " ++ name
-        (Just p) -> p
-
--- | lookupMain retrieves the main pattern from the grammar.
-lookupMain :: Grammar -> Pattern
-lookupMain g = lookupRef g (ValidRef "main")
diff --git a/src/VpaDerive.hs b/src/VpaDerive.hs
deleted file mode 100644
--- a/src/VpaDerive.hs
+++ /dev/null
@@ -1,100 +0,0 @@
--- |
--- This module contains a VPA (Visibly Pushdown Automaton) implementation of the internal derivative algorithm.
---
--- It is intended to be used for explanation purposes.
---
--- It shows how our algorithm is effectively equivalent to a visibly pushdown automaton.
-
-module VpaDerive (
-    derive      
-) where
-
-import qualified Data.Map.Strict as M
-import Control.Monad.State (State, runState, state, lift)
-import Data.Foldable (foldlM)
-import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
-
-import qualified Derive
-import Smart (Grammar, Pattern)
-import qualified Smart
-import IfExprs
-import Expr
-import Zip
-import Parsers
-
-mem :: Ord k => (k -> v) -> k -> M.Map k v -> (v, M.Map k v)
-mem f k m
-    | M.member k m = (m M.! k, m)
-    | otherwise = let res = f k
-        in (res, M.insert k res m)
-
-type VpaState = [Pattern]
-type StackElm = ([Pattern], Zipper)
-
-type Calls = M.Map VpaState ZippedIfExprs
-type Nullable = M.Map [Pattern] [Bool]
-type Returns = M.Map ([Pattern], Zipper, [Bool]) [Pattern]
-
-newtype Vpa = Vpa (Nullable, Calls, Returns, Grammar)
-
-newVpa :: Grammar -> Vpa
-newVpa g = Vpa (M.empty, M.empty, M.empty, g)
-
-nullable :: [Pattern] -> State Vpa [Bool]
-nullable key = state $ \(Vpa (n, c, r, g)) -> let (v', n') = mem (map Smart.nullable) key n;
-    in (v', Vpa (n', c, r, g))
-
-calls :: [Pattern] -> State Vpa ZippedIfExprs
-calls key = state $ \(Vpa (n, c, r, g)) -> let (v', c') = mem (zipIfExprs . Derive.calls g) key c;
-    in (v', Vpa (n, c', r, g))
-
-vpacall :: VpaState -> Label -> ExceptT String (State Vpa) (StackElm, VpaState)
-vpacall vpastate label = do {
-    zifexprs <- lift $ calls vpastate;
-    (nextstate, zipper) <- hoistExcept $ evalZippedIfExprs zifexprs label;
-    let 
-        stackelm = (vpastate, zipper)
-    ; 
-    return (stackelm, nextstate)
-}
-
-hoistExcept :: (Monad m) => Either e a -> ExceptT e m a
-hoistExcept = ExceptT . return
-
-returns :: ([Pattern], Zipper, [Bool]) -> State Vpa [Pattern]
-returns key = state $ \(Vpa (n, c, r, g)) -> 
-    let (v', r') = mem (\(ps, zipper, znulls) -> 
-            Derive.returns g (ps, unzipby zipper znulls)) key r
-    in (v', Vpa (n, c, r', g))
-
-vpareturn :: StackElm -> VpaState -> State Vpa VpaState
-vpareturn (vpastate, zipper) current = do {
-    zipnulls <- nullable current;
-    returns (vpastate, zipper, zipnulls)
-}
-
-deriv :: Tree t => VpaState -> t -> ExceptT String (State Vpa) VpaState
-deriv current tree = do {
-    (stackelm, nextstate) <- vpacall current (getLabel tree);
-    resstate <- foldlM deriv nextstate (getChildren tree);
-    lift $ vpareturn stackelm resstate
-}
-
-foldLT :: Tree t => Vpa -> VpaState -> [t] -> Either String [Pattern]
-foldLT _ current [] = return current
-foldLT m current (t:ts) = 
-    let (newstate, newm) = runState (runExceptT $ deriv current t) m
-    in case newstate of
-        (Left l) -> Left l
-        (Right r) -> foldLT newm r ts
-
--- |
--- derive is the derivative implementation for trees.
--- This implementation makes use of visual pushdown automata.
-derive :: Tree t => Grammar -> [t] -> Either String Pattern
-derive g ts = 
-    let start = [Smart.lookupMain g]
-    in case foldLT (newVpa g) start ts of
-        (Left l) -> Left $ show l
-        (Right [r]) -> return r
-        (Right rs) -> Left $ "Number of patterns is not one, but " ++ show rs
diff --git a/src/Xml.hs b/src/Xml.hs
deleted file mode 100644
--- a/src/Xml.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-
--- |
--- This module contains the XML Parser.
-
-module Xml (
-    decodeXML
-) where
-
-import Text.Read (readMaybe)
-import Text.XML.HXT.DOM.TypeDefs (XmlTree, XNode(..), blobToString, localPart)
-import Text.XML.HXT.Parser.XmlParsec (xread)
-import Data.Tree.NTree.TypeDefs (NTree(..))
-import qualified Data.Text as Text
-
-import Parsers
-
-instance Tree XmlTree where
-    getLabel (NTree n _ ) = either (String . Text.pack . ("XML Parse Error:" ++)) id (xmlLabel n)
-    getChildren (NTree _ cs) = cs
-
--- |
--- decodeXML returns a XmlTree, given an input string.
-decodeXML :: String -> [XmlTree]
-decodeXML = xread
-
-xmlLabel :: XNode -> Either String Label
-xmlLabel (XText s) = return $ parseLabel s
-xmlLabel (XBlob b) = return $ parseLabel $ blobToString b
-xmlLabel x@(XCharRef _) = fail $ "XCharRef not supported" ++ show x
-xmlLabel x@(XEntityRef _) = fail $ "XEntityRef not supported" ++ show x
-xmlLabel x@(XCmt _) = fail $ "XCmt not supported" ++ show x
-xmlLabel (XCdata s) = return $ parseLabel s
-xmlLabel x@XPi{} = fail $ "XPi not supported" ++ show x
-xmlLabel (XTag qname attrs) = return $ parseLabel (localPart qname) -- TODO attrs should be part of the children returned by getChildren
-xmlLabel x@XDTD{} = fail $ "XDTD not supported" ++ show x
-xmlLabel (XAttr qname) = return $ parseLabel (localPart qname)
-xmlLabel x@XError{} = fail $ "XError not supported" ++ show x
-
--- TODO what about other leaf types
-parseLabel :: String -> Label
-parseLabel s = maybe (String (Text.pack s)) Int (readMaybe s :: Maybe Int)
diff --git a/src/Zip.hs b/src/Zip.hs
deleted file mode 100644
--- a/src/Zip.hs
+++ /dev/null
@@ -1,47 +0,0 @@
--- |
--- This is an internal relapse module.
---
--- It zips patterns to reduce the state space.
-
-module Zip (
-    Zipper, zippy, unzipby
-) where
-
-import qualified Data.Set as S
-import Data.List (elemIndex)
-
-import Smart
-
-data ZipEntry = ZipVal Int | ZipZAny | ZipNotZAny
-    deriving (Eq, Ord)
-
--- |
--- Zipper represents compressed indexes
--- that resulted from compressing a list of patterns.
--- This can be used to uncompress a list of bools (nullability of patterns).
-newtype Zipper = Zipper [ZipEntry]
-    deriving (Eq, Ord)
-
--- | zippy compresses a list of patterns.
-zippy :: [Pattern] -> ([Pattern], Zipper)
-zippy ps =
-    let s = S.fromList ps
-        s' = S.delete ZAny s
-        s'' = S.delete emptySet s'
-        l = S.toAscList s''
-    in (l, Zipper $ map (indexOf l) ps)
-
-indexOf :: [Pattern] -> Pattern -> ZipEntry
-indexOf _ ZAny = ZipZAny
-indexOf _ Not{pat=ZAny} = ZipNotZAny
-indexOf ps p = case elemIndex p ps of
-    (Just i) -> ZipVal i
-
--- | unzipby uncompresses a list of bools (nullability of patterns).
-unzipby :: Zipper -> [Bool] -> [Bool]
-unzipby (Zipper z) bs = map (ofIndexb bs) z
-
-ofIndexb :: [Bool] -> ZipEntry -> Bool
-ofIndexb _ ZipZAny = True
-ofIndexb _ ZipNotZAny = False
-ofIndexb bs (ZipVal i) = bs !! i
diff --git a/stack.yaml b/stack.yaml
new file mode 100644
--- /dev/null
+++ b/stack.yaml
@@ -0,0 +1,65 @@
+# This file was automatically generated by 'stack init'
+#
+# Some commonly used options have been documented as comments in this file.
+# For advanced use and comprehensive documentation of the format, please see:
+# https://docs.haskellstack.org/en/stable/yaml_configuration/
+
+# Resolver to choose a 'specific' stackage snapshot or a compiler version.
+# A snapshot resolver dictates the compiler version and the set of packages
+# to be used for project dependencies. For example:
+#
+# resolver: lts-3.5
+# resolver: nightly-2015-09-21
+# resolver: ghc-7.10.2
+# resolver: ghcjs-0.1.0_ghc-7.10.2
+#
+# The location of a snapshot can be provided as a file or url. Stack assumes
+# a snapshot provided as a file might change, whereas a url resource does not.
+#
+# resolver: ./custom-snapshot.yaml
+# resolver: https://example.com/snapshots/2018-01-01.yaml
+resolver: lts-12.9
+
+# User packages to be built.
+# Various formats can be used as shown in the example below.
+#
+# packages:
+# - some-directory
+# - https://example.com/foo/bar/baz-0.0.2.tar.gz
+# - location:
+#    git: https://github.com/commercialhaskell/stack.git
+#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+#  subdirs:
+#  - auto-update
+#  - wai
+packages:
+- .
+# Dependency packages to be pulled from upstream that are not in the resolver
+# using the same syntax as the packages field.
+# (e.g., acme-missiles-0.3)
+# extra-deps: []
+
+# Override default flag values for local packages and extra-deps
+# flags: {}
+
+# Extra package databases containing global packages
+# extra-package-dbs: []
+
+# Control whether we use the GHC we find on the path
+# system-ghc: true
+#
+# Require a specific version of stack, using version ranges
+# require-stack-version: -any # Default
+# require-stack-version: ">=1.7"
+#
+# Override the architecture used by stack, especially useful on Windows
+# arch: i386
+# arch: x86_64
+#
+# Extra directories used by stack for building
+# extra-include-dirs: [/path/to/dir]
+# extra-lib-dirs: [/path/to/dir]
+#
+# Allow a newer minor version of GHC than the snapshot specifies
+# compiler-check: newer-minor
diff --git a/test/DeriveSpec.hs b/test/DeriveSpec.hs
--- a/test/DeriveSpec.hs
+++ b/test/DeriveSpec.hs
@@ -10,14 +10,16 @@
 import qualified Test.Tasty.HUnit as HUnit
 
 import Data.Tree
-import qualified Derive
-import qualified Parser
-import qualified Smart
-import qualified Parsers
 
+import qualified Data.Katydid.Parser.Parser as Parser
+
+import qualified Data.Katydid.Relapse.Derive as Derive
+import qualified Data.Katydid.Relapse.Parser as Relapse.Parser
+import qualified Data.Katydid.Relapse.Smart as Smart
+
 import Data.List.Index (imap)
 
-instance Parsers.Tree (Tree Parsers.Label) where
+instance Parser.Tree (Tree Parser.Label) where
     getLabel (Node l _) = l
     getChildren (Node _ cs) = cs
 
@@ -25,16 +27,16 @@
     T.testGroup "derive" [
         HUnit.testCase "two ors" $
             either HUnit.assertFailure (\(want,got) -> HUnit.assertEqual "(want,got)" want got) $ do {
-                input <- Parser.parseGrammar "(== 1 | !(== 2))" >>= Smart.compile;
-                want <- Parser.parseGrammar "*" >>= Smart.compile;
-                got <- Derive.derive input [Node (Parsers.Int 1) []];
+                input <- Relapse.Parser.parseGrammar "(== 1 | !(== 2))" >>= Smart.compile;
+                want <- Relapse.Parser.parseGrammar "*" >>= Smart.compile;
+                got <- Derive.derive input [Node (Parser.Int 1) []];
                 return (Smart.lookupMain want, got)
             }
         , HUnit.testCase "two interleaves" $
             either HUnit.assertFailure (\(want,got) -> HUnit.assertEqual "(want,got)" want got) $ do {
-                input <- Parser.parseGrammar "{== 1 ; !(== 2)}" >>= Smart.compile;
-                want <- Parser.parseGrammar "({<empty>;!(==2)}|{==1;*})" >>= Smart.compile;
-                got <- Derive.derive input [Node (Parsers.Int 1) []];
+                input <- Relapse.Parser.parseGrammar "{== 1 ; !(== 2)}" >>= Smart.compile;
+                want <- Relapse.Parser.parseGrammar "({<empty>;!(==2)}|{==1;*})" >>= Smart.compile;
+                got <- Derive.derive input [Node (Parser.Int 1) []];
                 return (Smart.lookupMain want, got)
             }
     ]
diff --git a/test/ParserSpec.hs b/test/ParserSpec.hs
--- a/test/ParserSpec.hs
+++ b/test/ParserSpec.hs
@@ -11,18 +11,18 @@
 
 import Text.ParserCombinators.Parsec (CharParser, parse, eof)
 
-import Parser
-import Expr
-import Exprs.Compare
-import Exprs.Contains
-import Exprs.Elem
-import Exprs.Length
-import Exprs.Logic
-import Exprs.Strings
-import Exprs.Type
-import Exprs.Var
-import Exprs
-import Ast
+import Data.Katydid.Relapse.Parser
+import Data.Katydid.Relapse.Expr
+import Data.Katydid.Relapse.Exprs.Compare
+import Data.Katydid.Relapse.Exprs.Contains
+import Data.Katydid.Relapse.Exprs.Elem
+import Data.Katydid.Relapse.Exprs.Length
+import Data.Katydid.Relapse.Exprs.Logic
+import Data.Katydid.Relapse.Exprs.Strings
+import Data.Katydid.Relapse.Exprs.Type
+import Data.Katydid.Relapse.Exprs.Var
+import Data.Katydid.Relapse.Exprs
+import Data.Katydid.Relapse.Ast
 
 import UserDefinedFuncs
 
diff --git a/test/RelapseSpec.hs b/test/RelapseSpec.hs
--- a/test/RelapseSpec.hs
+++ b/test/RelapseSpec.hs
@@ -7,11 +7,13 @@
 import qualified Test.Tasty as T
 import qualified Test.Tasty.HUnit as HUnit
 
-import Relapse
-import Json
+import qualified Data.Katydid.Parser.Json as Json
+
+import qualified Data.Katydid.Relapse.Relapse as Relapse
+import Data.Katydid.Relapse.Expr (AnyExpr)
+import Data.Katydid.Relapse.Exprs (mkExpr)
+
 import UserDefinedFuncs
-import Expr (AnyExpr)
-import Exprs (mkExpr)
 
 tests = T.testGroup "Relapse" [
     HUnit.testCase "parseGrammar success" $ either HUnit.assertFailure (\_ -> return ()) $
diff --git a/test/Suite.hs b/test/Suite.hs
--- a/test/Suite.hs
+++ b/test/Suite.hs
@@ -11,16 +11,16 @@
 import System.FilePath (FilePath, (</>), takeExtension, takeBaseName, takeDirectory)
 import Text.XML.HXT.DOM.TypeDefs (XmlTree)
 
-import Parsers (Tree)
-import Smart (Grammar, Pattern, nullable, compile)
-import qualified Ast
-import Json (JsonTree, decodeJSON)
-import Xml (decodeXML)
-import Parser (parseGrammar)
+import Data.Katydid.Parser.Parser (Tree)
+import Data.Katydid.Parser.Json (JsonTree, decodeJSON)
+import Data.Katydid.Parser.Xml (decodeXML)
 
-import qualified Derive
-import qualified MemDerive
-import qualified VpaDerive
+import Data.Katydid.Relapse.Smart (Grammar, Pattern, nullable, compile)
+import qualified Data.Katydid.Relapse.Ast as Ast
+import Data.Katydid.Relapse.Parser (parseGrammar)
+import qualified Data.Katydid.Relapse.Derive as Derive
+import qualified Data.Katydid.Relapse.MemDerive as MemDerive
+import qualified Data.Katydid.Relapse.VpaDerive as VpaDerive
 
 tests :: [TestSuiteCase] -> T.TestTree
 tests testSuiteCases = 
diff --git a/test/UserDefinedFuncs.hs b/test/UserDefinedFuncs.hs
--- a/test/UserDefinedFuncs.hs
+++ b/test/UserDefinedFuncs.hs
@@ -9,7 +9,7 @@
 
 import Data.Numbers.Primes (isPrime)
 
-import Expr
+import Data.Katydid.Relapse.Expr
 
 -- |
 -- userLib is a library of user defined functions that can be passed to the parser.
