diff --git a/HXQ-unstable.hs b/HXQ-unstable.hs
--- a/HXQ-unstable.hs
+++ b/HXQ-unstable.hs
@@ -3,7 +3,7 @@
 - The main program of the XQuery Compiler
 - **** UNSTABLE *****
 - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
-- Date: 05/02/2008
+- Date: 07/24/2008
 -
 ---------------------------------------------------------------}
 
@@ -14,15 +14,15 @@
 import Packages
 import PackageConfig
 import System.IO
-import XML.HXQ.XQuery
+import Text.XML.HXQ.XQuery
 import System.Environment
 import qualified Control.Exception
-import XML.HXQ.Compiler(functions)
-import XML.HXQ.Interpreter(evalInput)
+import Text.XML.HXQ.Compiler(functions)
+import Text.XML.HXQ.Interpreter(evalInput)
 
 
-version = "0.8.4"
-default_system_path = "/usr/local/lib/ghc-6.8.2"
+version = "0.8.5"
+default_system_path = "/usr/local/lib/ghc-6.8.3"
 default_hxq_path = "./"
 
 
@@ -56,7 +56,7 @@
                    Just file -> do query <- readFile file
                                    let qf = map (\c -> if c=='\"' then '\'' else c)
                                                 (foldr1 (\a r -> a++" "++r) (lines query))
-                                       pr = "{-# OPTIONS_GHC -fth #-}\nmodule Main where\nimport XML.HXQ.XQuery\n\nmain = do res <- $(xq \""
+                                       pr = "{-# OPTIONS_GHC -fth #-}\nmodule Main where\nimport Text.XML.HXQ.XQuery\n\nmain = do res <- $(xq \""
                                             ++ qf ++ "\")\n          putXSeq res\n"
                                        Just ofile = lookup "o" env
                                    writeFile ofile pr
@@ -64,7 +64,7 @@
                            dflags0 <- getSessionDynFlags session
                            (dflags1,b) <- parseDynamicFlags dflags0 ["-fglasgow-exts", "-O2", "-fth", "-fobject-code",
                                                                      --"-package HXQ", "-package ghc"]
-                                                                     "-i"++hxq_path++"XML/HXQ/:"++hxq_path++"hxml-0.2"]
+                                                                     "-i"++hxq_path++"Text/XML/HXQ/:"++hxq_path++"hxml-0.2"]
                            (dflags2, _) <- initPackages dflags1
                            setSessionDynFlags session dflags2
                            --load session LoadAllTargets
@@ -84,11 +84,11 @@
                                              _ <- runStmt session query SingleStep
                                              return ()
                              _ -> case lookup "p" env of
-                                    Just query -> do _ <- runStmt session ("do result <- $(XML.HXQ.XQuery.xq \""++query
-                                                                           ++"\"); XML.HXQ.XQuery.putXSeq result") SingleStep
+                                    Just query -> do _ <- runStmt session ("do result <- $(Text.XML.HXQ.XQuery.xq \""++query
+                                                                           ++"\"); Text.XML.HXQ.XQuery.putXSeq result") SingleStep
                                                      return ()
                                     _ -> do putStrLn "To write an XQuery in multiple lines, wrap it in {}"
-                                            evalInput (\s vs fs -> let query = "do result <- $(XML.HXQ.XQuery.xq \""++s++"\");"
-                                                                               ++"XML.HXQ.XQuery.putXSeq result"
+                                            evalInput (\s vs fs -> let query = "do result <- $(Text.XML.HXQ.XQuery.xq \""++s++"\");"
+                                                                               ++"Text.XML.HXQ.XQuery.putXSeq result"
                                                                    in Control.Exception.catch (do runStmt session query SingleStep; return (vs,fs))
                                                                               (\e -> do putStrLn (show e); return (vs,fs))) [] []
diff --git a/HXQ.cabal b/HXQ.cabal
--- a/HXQ.cabal
+++ b/HXQ.cabal
@@ -1,6 +1,6 @@
 Cabal-Version:       >= 1.2
 Name:                HXQ
-Version:             0.8.4
+Version:             0.8.5
 Synopsis:            A Compiler from XQuery to Haskell
 Description:         
         HXQ is a fast and space-efficient compiler from XQuery (the standard
@@ -38,9 +38,9 @@
   hxml-0.2/00-README.txt
 
 Library
-  Exposed-Modules:     XML.HXQ.XQuery
-  Other-Modules:       XML.HXQ.XTree, XML.HXQ.Compiler, XML.HXQ.Interpreter, XML.HXQ.Parser,
-                       XML.HXQ.Optimizer, XML.HXQ.DB, XML.HXQ.DBConnect,
+  Exposed-Modules:     Text.XML.HXQ.XQuery
+  Other-Modules:       Text.XML.HXQ.XTree, Text.XML.HXQ.Compiler, Text.XML.HXQ.Interpreter, Text.XML.HXQ.Parser,
+                       Text.XML.HXQ.Optimizer, Text.XML.HXQ.DB, Text.XML.HXQ.DBConnect,
                        HXML, DTD, LLParsing, TreeBuild, XMLParse, ETree, Misc, Tree,
                        XMLScanner, AssocList, PrintXML, XML
   hs-source-dirs:      . hxml-0.2
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -2,7 +2,7 @@
 -
 - The main program of the XQuery interpreter
 - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
-- Date: 06/26/2008
+- Date: 07/24/2008
 -
 ---------------------------------------------------------------}
 
@@ -11,11 +11,11 @@
 
 import System.Environment
 import qualified Control.Exception
-import XML.HXQ.Compiler(functions)
-import XML.HXQ.Interpreter(evalInput,xqueryE)
-import XML.HXQ.XQuery
+import Text.XML.HXQ.Compiler(functions)
+import Text.XML.HXQ.Interpreter(evalInput,xqueryE)
+import Text.XML.HXQ.XQuery
 
-version = "0.8.4"
+version = "0.8.5"
 
 
 parseEnv :: [String] -> [(String,String)]
@@ -53,7 +53,7 @@
                    Just file -> do query <- readFile file
                                    let qf = map (\c -> if c=='\"' then '\'' else c)
                                                 (foldr1 (\a r -> a++" "++r) (lines query))
-                                       pr = "{-# OPTIONS_GHC -fth #-}\nmodule Main where\nimport XML.HXQ.XQuery\n\nmain = do res <- $(xq \""
+                                       pr = "{-# OPTIONS_GHC -fth #-}\nmodule Main where\nimport Text.XML.HXQ.XQuery\n\nmain = do res <- $(xq \""
                                             ++ qf ++ "\")\n          putXSeq res\n"
                                        Just ofile = lookup "o" env
                                    writeFile ofile pr
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 hxml = hxml-0.2
-hxq = XML/HXQ
+hxq = Text/XML/HXQ
 options = -O2
 parser = $(hxq)/Parser.hs
 
diff --git a/Test1.hs b/Test1.hs
--- a/Test1.hs
+++ b/Test1.hs
@@ -2,7 +2,7 @@
 -
 - A main program to test the XQuery processor
 - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
-- Date: 03/30/2008
+- Date: 07/24/2008
 -
 ---------------------------------------------------------------}
 
@@ -10,7 +10,7 @@
 
 module Main where
 
-import XML.HXQ.XQuery
+import Text.XML.HXQ.XQuery
 
 
 f(d,s) = $(xe "<student dept='{$d/text()}'>{$s//firstname/text(),$s//lastname/text()}</student>")
diff --git a/Test2.hs b/Test2.hs
--- a/Test2.hs
+++ b/Test2.hs
@@ -3,7 +3,7 @@
 - Testing the  XQuery compiler on a large file
 - Download dblp.xml from http://dblp.uni-trier.de/xml/
 - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
-- Date: 03/30/2008
+- Date: 07/24/2008
 -
 ---------------------------------------------------------------}
 
@@ -11,7 +11,7 @@
 
 module Main where
 
-import XML.HXQ.XQuery
+import Text.XML.HXQ.XQuery
 
 
 f(x,y) = $(xe "<a>{$x,$y}</a>")
diff --git a/TestDB.hs b/TestDB.hs
--- a/TestDB.hs
+++ b/TestDB.hs
@@ -4,7 +4,7 @@
 - To create the database load the file data/company.sql in sqlite3
 -
 - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
-- Date: 05/21/2008
+- Date: 07/24/2008
 -
 ---------------------------------------------------------------}
 
@@ -12,7 +12,7 @@
 
 module Main where
 
-import XML.HXQ.XQuery
+import Text.XML.HXQ.XQuery
 
 
 main = do db <- connect "myDB"
@@ -23,4 +23,4 @@
                      ++"                'English')                          "
                      ++"  return <result>{$r/fname,$r/dname}</result>       ")) db
           putXSeq e
-          disconnect db
+          -- disconnect db
diff --git a/TestDB2.hs b/TestDB2.hs
--- a/TestDB2.hs
+++ b/TestDB2.hs
@@ -3,7 +3,7 @@
 - A main program to test XML shredding and publishing
 -
 - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
-- Date: 06/12/2008
+- Date: 07/24/2008
 -
 ---------------------------------------------------------------}
 
@@ -11,7 +11,7 @@
 
 module Main where
 
-import XML.HXQ.XQuery
+import Text.XML.HXQ.XQuery
 
 
 main = do db <- connect "myDB"
@@ -20,4 +20,4 @@
                          ++ " where $s//lastname='Galanis'                 "
                          ++ " return $s//gpa      ")) db
           putXSeq res
-          disconnect db
+          -- disconnect db
diff --git a/Text/XML/HXQ/Compiler.hs b/Text/XML/HXQ/Compiler.hs
new file mode 100644
--- /dev/null
+++ b/Text/XML/HXQ/Compiler.hs
@@ -0,0 +1,834 @@
+{-------------------------------------------------------------------------------------
+-
+- A Compiler from XQuery to Haskell
+- Programmer: Leonidas Fegaras
+- Email: fegaras@cse.uta.edu
+- Web: http://lambda.uta.edu/
+- Creation: 02/15/08, last update: 07/24/08
+- 
+- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
+- This material is provided as is, with absolutely no warranty expressed or implied.
+- Any use is at your own risk. Permission is hereby granted to use or copy this program
+- for any purpose, provided the above notices are retained on all copies.
+-
+--------------------------------------------------------------------------------------}
+
+
+{-# OPTIONS_GHC -fth -fbang-patterns #-}
+
+module Text.XML.HXQ.Compiler where
+
+import Data.List
+import Control.Monad
+import Char(isDigit,toLower)
+import List(sortBy)
+import Language.Haskell.TH
+import XMLParse(parseDocument)
+import HXML(AttList)
+import Text.XML.HXQ.Parser
+import Text.XML.HXQ.XTree
+import Text.XML.HXQ.Optimizer
+import Text.XML.HXQ.DB
+
+
+{--------------- XPath Steps ---------------------------------------------------------}
+
+
+current_step :: Tag -> XTree -> XSeq
+current_step m x
+    = case x of
+        XElem k _ _ _ _ | (k==m || m=="*") -> [x]
+        _ -> []
+
+
+-- XPath step /tag or /*
+child_step :: Tag -> XTree -> XSeq
+child_step m x
+    = case x of
+        XElem _ _ _ _ bs
+            -> foldr (\b s -> case b of
+                                XElem k _ _ _ _ | (k==m || m=="*") -> b:s
+                                _ -> s) [] bs
+        _ -> []
+
+
+-- XPath step //tag or //*
+descendant_step :: Tag -> XTree -> XSeq
+descendant_step m (x@(XElem t _ _ _ cs))
+    | m==t || m=="*"
+    = x:(concatMap (descendant_step m) cs)
+descendant_step m (XElem t _ _ _ cs) = concatMap (descendant_step m) cs
+descendant_step m _ = []
+
+
+-- It's like //* but has tagged children, which are derived statically
+-- After examing 100 children it gives up: this avoids space leaks
+descendant_any_with_tagged_children :: [Tag] -> XTree -> XSeq
+descendant_any_with_tagged_children tags (x@(XElem t _ _ _ cs))
+    | all (\tag -> foldr (\b s -> case b of
+                                    (XElem k _ _ _ _) -> s || k == tag
+                                    _ -> s) False cs100) tags
+    = x:(concatMap (descendant_any_with_tagged_children tags) cs)
+    where cs100 = take 100 cs
+descendant_any_with_tagged_children tags (XElem t _ _ _ cs)
+    = concatMap (descendant_any_with_tagged_children tags) cs
+descendant_any_with_tagged_children tags _ = []
+
+
+-- XPath step /@attr or /@*
+attribute_step :: Tag -> XTree -> XSeq
+attribute_step m x
+    = case x of
+        (XElem _ al _ _ _) -> foldr (\(k,v) s -> if k==m || m=="*"
+                                                 then (XText v):s
+                                                 else s) [] al
+        _ -> []
+
+
+-- XPath step //@attr or //@*
+attribute_descendant_step :: Tag -> XTree -> XSeq
+attribute_descendant_step m (x@(XElem _ al _ _ cs))
+    = foldr (\(k,v) s -> if k==m || m=="*"
+                         then (XText v):s
+                         else s)
+            (concatMap (attribute_descendant_step m) cs) al
+attribute_descendant_step m _ = []
+
+
+-- NOT USED: XPath step /..
+parent_step :: Tag -> XTree -> XSeq
+parent_step _ (XElem _ _ _ p _) = [p]
+parent_step _ e = error ("Cannot derive the parent of "++show e)
+
+
+{------------ Functions --------------------------------------------------------------}
+
+
+-- find the value of a variable in an association list
+findV var env
+  = case filter (\(n,_) -> n==var) env of
+      (_,b):_ -> b
+      _ -> error ("Undefined variable: "++var)
+
+-- is the variable defined in the association list?
+memV var env
+  = case filter (\(n,_) -> n==var) env of
+      (_,b):_ -> True
+      _ -> False
+
+
+-- like foldr but with an index
+foldir :: (a -> Int -> b -> b) -> b -> [a] -> Int -> b
+foldir c n [] i = n
+foldir c n (x:xs) i = c x i (foldir c n xs (i+1))
+
+
+trueXT = XBool True
+falseXT = XBool False
+
+
+readNum :: String -> Maybe XTree
+readNum cs = case span isDigit cs of
+               (n,[]) -> Just (XInt (read n))
+               (n,'.':rest) -> case span isDigit rest of
+                                 (k,[]) -> Just (XFloat (read (n++('.':k))))
+                                 _ -> Nothing
+               _ -> Nothing
+
+
+text :: XSeq -> XSeq
+text xs = foldr (\x r -> case x of
+                           XElem _ _ _ _ zs
+                               -> (filter (\a -> case a of XText _ -> True; XInt _ -> True;
+                                                           XFloat _ -> True; XBool _ -> True; _ -> False) zs)++r
+                           XText _ -> x:r
+                           XInt _ -> x:r
+                           XFloat _ -> x:r
+                           XBool _ -> x:r
+                           _ -> r) [] xs
+
+
+toString :: XSeq -> [String]
+toString xs = map (\x -> case x of 
+                           XText t -> t
+                           XInt n -> show n
+                           XFloat n -> show n
+                           XBool n -> show n)
+                  (text xs)
+
+
+-- concatenate text with no padding (for element content)
+appendText :: [XSeq] -> XSeq
+appendText [] = []
+appendText [x] = x
+appendText (x:xs) = x++[XNoPad]++appendText xs
+
+
+toNum :: XSeq -> XSeq
+toNum xs = foldr (\x r -> case x of
+                            XInt n -> x:r
+                            XFloat n -> x:r
+                            XText s -> case readNum s of
+                                         Just t -> t:r
+                                         _ -> r
+                            _ -> r) [] (text xs)
+
+
+toFloat :: XTree -> Float
+toFloat (XText s) = case readNum s of
+                      Just (XInt n) -> fromIntegral n
+                      Just (XFloat n) -> n
+                      _ -> error("Cannot convert to a float: "++s)
+toFloat (XInt n) = fromIntegral n
+toFloat (XFloat n) = n
+toFloat x = error("Cannot convert to a float: "++(show x))
+
+
+mean :: (Fractional t) => [t] -> t
+mean = uncurry (/) . foldl' (\(!s, !n) x -> (s+x, n+1)) (0,0.0)
+
+
+contains :: String -> String -> Bool
+contains text word
+    = let len = length word
+          c xs | ((take len xs) == word) = True
+          c (_:xs) = c xs
+          c _ = False
+      in c text
+
+
+distinct :: Eq a => [a] -> [a]
+distinct = foldl (\r a -> if elem a r then r else r++[a]) []
+
+
+arithmetic :: (Float -> Float -> Float) -> XTree -> XTree -> XTree
+arithmetic op (XInt n) (XInt m) = XInt (round (op (fromIntegral n) (fromIntegral m)))
+arithmetic op (XFloat n) (XFloat m) = XFloat (op n m)
+arithmetic op (XFloat n) (XInt m) = XFloat (op n (fromIntegral m))
+arithmetic op (XInt n) (XFloat m) = XFloat (op (fromIntegral n) m)
+
+
+compareXTrees :: XTree -> XTree -> Ordering
+compareXTrees (XElem _ _ _ _ _) _ = EQ
+compareXTrees _ (XElem _ _ _ _ _) = EQ
+compareXTrees (XInt n) (XInt m) = compare n m
+compareXTrees (XFloat n) (XInt m) = compare n (fromIntegral m)
+compareXTrees (XInt n) (XFloat m) = compare (fromIntegral n) m
+compareXTrees (XFloat n) (XFloat m) = compare n m
+compareXTrees (XText n) (XText m) = compare n m
+compareXTrees x y = compare (toFloat x) (toFloat y)
+
+
+strictCompareOne [XInt n] [XInt m] = compare n m
+strictCompareOne [XFloat n] [XFloat m] = compare n m
+strictCompareOne [XFloat n] [XInt m] = compare n (fromIntegral m)
+strictCompareOne [XInt n] [XFloat m] = compare (fromIntegral n) m
+strictCompareOne [XText n] [XText m] = compare n m
+strictCompareOne x y = error ("Illegal operands in strict comparison: "++(show x)++" "++(show y))
+
+strictCompare :: XSeq -> XSeq -> Ordering
+strictCompare [XElem _ _ _ _ x] [XElem _ _ _ _ y] = strictCompareOne x y
+strictCompare x [XElem _ _ _ _ y] = strictCompareOne x y
+strictCompare [XElem _ _ _ _ x] y = strictCompareOne x y
+strictCompare x y = strictCompareOne x y
+
+compareXSeqs :: Bool -> XSeq -> XSeq -> Ordering
+compareXSeqs ord xs ys
+    = let comps = [ compareXTrees x y | x <- xs, y <- ys ]
+      in if ord
+            then if all (\x -> x == LT) comps
+                    then LT
+                 else if all (\x -> x == GT) comps
+                    then GT
+                 else EQ
+         else if all (\x -> x == LT) comps
+                 then GT
+              else if all (\x -> x == GT) comps
+                 then LT
+              else EQ
+
+
+conditionTest :: XSeq -> Bool
+conditionTest [] = False
+conditionTest [XText ""] = False
+conditionTest [XInt 0] = False
+conditionTest [XBool False] = False
+conditionTest _ = True
+
+
+-- XPath steps
+paths :: [(Tag,Q Exp)]
+paths = [ ( "current_step", [| current_step |] ),
+          ( "child_step", [| child_step |] ),
+          ( "descendant_step", [| descendant_step |] ),
+          ( "attribute_step", [| attribute_step |] ),
+          ( "attribute_descendant_step", [| attribute_descendant_step |] ),
+          ( "parent_step", [| parent_step |] )
+        ]
+
+
+type Function = [Q Exp] -> Q Exp
+
+-- System functions: they can also be defined as Haskell functions of type (XSeq,...,XSeq) -> XSeq
+-- but here we make sure they are unfolded and fused with the rest of the query
+functions :: [(Tag,Int,Function)]
+functions = [ ( "=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ] |] ),
+              ( "!=", 2, \[xs,ys] -> [| if null [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ]
+                                        then [trueXT]
+                                        else [falseXT] |] ),
+              ( ">", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == GT ] |] ),
+              ( "<", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == LT ] |] ),
+              ( ">=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y `elem` [GT,EQ] ] |] ),
+              ( "<=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y `elem` [LT,EQ] ] |] ),
+              ( "eq", 2, \[xs,ys] -> [| if strictCompare $xs $ys == EQ then [trueXT] else [falseXT] |] ),
+              ( "neq", 2, \[xs,ys] -> [| if strictCompare $xs $ys /= EQ then [trueXT] else [falseXT] |] ),
+              ( "lt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == LT then [trueXT] else [falseXT] |] ),
+              ( "gt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == GT then [trueXT] else [falseXT] |] ),
+              ( "le", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [LT,EQ] then [trueXT] else [falseXT] |] ),
+              ( "ge", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [GT,EQ] then [trueXT] else [falseXT] |] ),
+              ( "<<", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ _ <- $xs, XElem _ _ oy _ _ <- $ys, ox < oy ] |] ),
+              ( ">>", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ _ <- $xs, XElem _ _ oy _ _ <- $ys, ox > oy ] |] ),
+              ( "is", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ _ <- $xs, XElem _ _ oy _ _ <- $ys, ox == oy ] |] ),
+              ( "+", 2, \[xs,ys] -> [| [ arithmetic (+) x y | x <- toNum $xs, y <- toNum $ys ] |] ),
+              ( "-", 2, \[xs,ys] -> [| [ arithmetic (-) x y | x <- toNum $xs, y <- toNum $ys ] |] ),
+              ( "*", 2, \[xs,ys] -> [| [ arithmetic (*) x y | x <- toNum $xs, y <- toNum $ys ] |] ),
+              ( "div", 2, \[xs,ys] -> [| [ arithmetic (/) x y | x <- toNum $xs, y <- toNum $ys ] |] ),
+              ( "idiv", 2, \[xs,ys] -> [| [ XInt (div x y) | (XInt x) <- toNum $xs, (XInt y) <- toNum $ys ] |] ),
+              ( "mod", 2, \[xs,ys] -> [| [ XInt (mod x y) | (XInt x) <- toNum $xs, (XInt y) <- toNum $ys ] |] ),
+              ( "uplus", 1, \[xs] -> [| [ x | x <- toNum $xs ] |] ),
+              ( "uminus", 1, \[xs] -> [| [ case x of XInt n -> XInt (-n); XFloat n -> XFloat (-n) | x <- toNum $xs ] |] ),
+              ( "and", 2, \[xs,ys] -> [| if (conditionTest $xs) && (conditionTest $ys) then [trueXT] else [falseXT] |] ),
+              ( "or", 2, \[xs,ys] -> [| if (conditionTest $xs) || (conditionTest $ys) then [trueXT] else [falseXT] |] ),
+              ( "not", 1, \[xs] -> [| if (conditionTest $xs) then [falseXT] else [trueXT] |] ),
+              ( "some", 1, \[xs] -> [| if (conditionTest $xs) then [trueXT] else [falseXT] |] ),
+              ( "count", 1, \[xs] -> [| [ XInt (length $xs) ] |] ),
+              ( "sum", 1, \[xs] -> [| [ XFloat (sum [ toFloat x | x <- toNum $xs ]) ] |] ),
+              ( "avg", 1, \[xs] -> [| [ XFloat (mean [ toFloat x | x <- toNum $xs ]) ] |] ),
+              ( "min", 1, \[xs] -> [| [ XFloat (minimum [ toFloat x | x <- toNum $xs ]) ] |] ),
+              ( "max", 1, \[xs] -> [| [ XFloat (maximum [ toFloat x | x <- toNum $xs ]) ] |] ),
+              ( "to", 2, \[xs,ys] -> [| [ XInt i | XInt n <- toNum $xs, XInt m <- toNum $ys, i <- [n..m] ] |] ),
+              ( "text", 1, \[xs] -> [| text $xs |] ),
+              ( "string", 1, \[xs] -> [| text $xs |] ),
+              ( "data", 1, \[xs] -> [| text $xs |] ),
+              ( "node", 1, \[xs] -> [| [ w | w@(XElem _ _ _ _ _) <- $xs ] |] ),
+              ( "exists", 1, \[xs] -> [| [ XBool (not (null $xs)) ] |] ),
+              ( "empty", 0, \[] -> [| [] |] ),
+              ( "true", 0, \[] -> [| [trueXT] |] ),
+              ( "false", 0, \[] -> [| [] |] ),
+              ( "if", 3, \[cs,ts,es] -> [| if conditionTest $cs then $ts else $es |] ),
+              ( "element", 2, \[tags,xs] -> [| [ x | tag <- toString $tags, x@(XElem t _ _ _ _) <- $xs, (t==tag || tag=="*") ] |] ),
+              ( "attribute", 2, \[tags,xs] -> [| [ z | tag <- toString $tags, x <- $xs, z <- attribute_step tag x ] |] ),
+              ( "name", 1, \[xs] -> [| [ XText tag | XElem tag _ _ _ _ <- $xs ] |] ),
+              ( "contains", 2, \[xs,text] -> [| [ trueXT | x <- toString $xs, t <- toString $text, contains x t ] |] ),
+              ( "substring", 3, \[xs,n1,n2] -> [| [ XText (take m2 (drop (m1-1) x)) | x <- toString $xs,
+                                                    XInt m1 <- toNum $n1, XInt m2 <- toNum $n2 ] |] ),
+              ( "concatenate", 2, \[xs,ys] -> [| $xs ++ $ys |] ),
+              ( "distinct-values", 1, \[xs] -> [| distinct $xs |] ),
+              ( "union", 2, \[xs,ys] -> [| distinct ($xs ++ $ys) |] ),
+              ( "intersect", 2, \[xs,ys] -> [| filter (\x -> elem x $ys) $xs |] ),
+              ( "except", 2, \[xs,ys] -> [| filter (\x -> not (elem x $ys)) $xs  |] ),
+              ( "reverse", 1, \[xs] -> [| reverse $xs |] )
+            ]
+
+
+-- functions to be used by the interpreter
+-- when evaluated, it gives [(String,Int,[XSeq]->XSeq)]
+iFunctions :: Q Exp
+iFunctions = foldr (\(fname,len,f) r
+                        -> let vars = map (\i -> mkName ("v_"++(show i))) [1..len]
+                               entry = tupE [litE (StringL fname),litE (IntegerL (toInteger len)),
+                                             lamE [listP (map varP vars)] (f (map varE vars))]
+                           in [| $entry : $r |]) [| [] |] functions
+
+
+-- XPath steps to be used by the interpreter
+-- when evaluated, it gives [(String,Tag->XTree->XSeq)]
+pFunctions = foldr (\(pname,p) r -> let pn = litE (StringL pname) in [| ($pn,$p) : $r |]) [| [] |] paths
+
+
+-- make a function call
+callF :: Tag -> Function
+callF fname args = case filter (\(n,_,_) -> n == fname || ("fn:"++n)==fname) functions of
+                     (_,len,f):_ -> if (length args) == len
+                                       then f args
+                                    else error ("wrong number of arguments in function call: " ++ fname)
+                     _ ->     -- otherwise, it must be a Haskell function of type (XSeq,...,XSeq) -> XSeq
+                          let itp = case args of
+                                      [] -> [t| () |]
+                                      [_] -> [t| XSeq |]
+                                      _ -> foldr (\_ r -> appT r [t| XSeq |]) (appT (tupleT (length args)) [t| XSeq |])
+                                                 (tail args)
+                              fn = sigE (varE (mkName fname))
+                                        (appT (appT arrowT itp) [t| XSeq |])
+                          in appE fn (tupE args)
+
+
+{------------ Compiler ---------------------------------------------------------------}
+
+
+undef1 = [| error "Undefined XQuery context (.)" |]
+undef2 = [| error "Undefined position()" |]
+undef3 = [| error "Undefined last()" |]
+
+
+-- does the expression contain a last()?
+containsLast :: Ast -> Bool
+containsLast (Ast "call" [Avar "last"]) = True
+containsLast (Ast f _) | elem f ["let","for","predicate"] = False
+containsLast (Ast "step" _) = False
+containsLast (Ast _ args) = or (map containsLast args)
+containsLast _ = False
+
+
+-- calculate the maximum position value used in a predicate, if there is one
+maxPosition :: Ast -> Ast -> Int
+maxPosition position e
+    = case e of
+        Ast "call" [Avar f,p,Aint n]
+            | f `elem` ["=","<","<=","eq","lt","le"] && p == position
+            -> n
+        Ast "call" [Avar f,Aint n,p]
+            | f `elem` ["=",">",">=","eq","gt","ge"] && p == position
+            -> n
+        Ast "let" [Avar x,source,body]
+            -> if position == Avar x
+               then 0 else minp (maxPosition position source) (maxPosition position body)
+        Ast "for" [Avar x,Avar i,source,body]
+            -> if position == Avar x || position == Avar i
+               then 0 else minp (maxPosition position source) (maxPosition position body)
+        Ast "predicate" [pred,body]
+            -> minp (maxPosition position pred) (maxPosition position body)
+        Ast "call" [Avar "and",x,y]
+            -> minp (maxPosition position x) (maxPosition position y)
+        Ast "call" [Avar "or",x,y]
+            -> max (maxPosition position x) (maxPosition position y)
+        _ -> 0
+    where minp x y = if x == 0 then y else if y == 0 then x else min x y
+
+
+pathPosition = Ast "call" [Avar "position"]
+
+
+parent_error = error "constructed elements have no parent"
+
+
+-- extract the QName
+qName :: XSeq -> Tag
+qName [XText s] = s
+qName e = error ("Invalid QName: "++(show e))
+
+
+-- Each XPath predicate must calculate position() and last() from its input XSeq
+-- if last() is used, then the evaluation is blocking (need to store the whole input XSeq)
+compilePredicates :: [Ast] -> Q Exp -> Bool -> Q Exp
+compilePredicates [] xs _ = xs
+compilePredicates ((Aint n):preds) xs _   -- shortcut that improves laziness
+    = compilePredicates preds
+            [| [ $xs !! $(litE (IntegerL (toInteger (n-1)))) ] |] True
+compilePredicates (pred:preds) xs True    -- top-k like
+    | maxPosition pathPosition pred > 0
+    = compilePredicates (pred:preds)
+           [| take $(litE (IntegerL (toInteger (maxPosition pathPosition pred)))) $xs |] False
+compilePredicates (pred:preds) xs _
+    | containsLast pred         -- blocking: use only when last() is used in the predicate
+    = compilePredicates preds
+            [| let bl = $xs
+                   len = length bl
+               in foldir (\x i r -> if case $(compile pred [| x |] [| [XInt i] |] [| [XInt len] |] "") of
+                                         [XInt k] -> k == i               -- indexing
+                                         b -> conditionTest b
+                                    then x:r else r) [] bl 1 |] True
+compilePredicates (pred:preds) xs _
+    = compilePredicates preds
+            [| foldir (\x i r -> if case $(compile pred [| x |] [| [XInt i] |] undef3 "") of
+                                      [XInt k] -> k == i               -- indexing
+                                      b -> conditionTest b
+                                 then x:r else r) [] $xs 1 |] True
+
+
+-- Compile the AST e into Haskell code
+-- context: context node (XPath .)
+-- position: the element position in the parent sequence (XPath position())
+-- last: the length of the parent sequence (XPath last())
+-- effective_axis: the XPath axis in /axis::tag(exp)
+--        (eg, the effective axis of //(A | B) is "descendant_step"
+compile :: Ast -> Q Exp -> Q Exp -> Q Exp -> String -> Q Exp
+compile e context position last effective_axis
+  = case e of
+      Avar "." -> [| [ $context :: XTree ] |]
+      Avar v -> let x = varE (mkName v)
+                in [| $x :: XSeq |]
+      Aint n -> let x = litE (IntegerL (toInteger n))
+                in [| [ XInt $x ] |]
+      Afloat n -> let x = litE (RationalL (toRational n))
+                  in [| [ XFloat $x ] |]
+      Astring s -> let x = litE (StringL s)
+                   in [| [ XText $x ] |]
+      Ast "context" [v,Astring dp,body]
+          -> [| foldr (\x r -> $(compile body [| x |] position last dp)++r)
+                      [] $(compile v context position last effective_axis) |]
+      Ast "call" [Avar "position"]
+          -> position
+      Ast "call" [Avar "last"]
+          -> last
+      Ast "child_step" [tag, Avar "."]
+          | effective_axis /= ""
+          -> compile (Ast effective_axis [tag, Avar "."]) context position last ""
+      Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
+          -> let bc = compile body context position last effective_axis
+                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
+             in [| foldr (\x r -> $(compilePredicates predicates [| descendant_any_with_tagged_children $ts x |] True)++r)
+                         [] $bc |]
+      Ast "step" ((Ast path_step [Astring tag,body]):predicates)
+          |  memV path_step paths
+          -> let bc = compile body context position last effective_axis
+                 tc = litE (stringL tag)
+             in [| foldr (\x r -> $(compilePredicates predicates [| $(findV path_step paths) $tc x |] True)++r)
+                         [] $bc |]
+      Ast "descendant_any" (body:tags)
+          -> let bc = compile body context position last effective_axis
+                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
+             in [| foldr (\x r -> (descendant_any_with_tagged_children $ts x)++r) [] $bc |]
+      Ast path_step [Astring tag,body]
+          |  memV path_step paths
+          -> let bc = compile body context position last effective_axis
+                 tc = litE (stringL tag)
+             in [| foldr (\x r -> ($(findV path_step paths) $tc x)++r) [] $bc |]
+      Ast "step" (exp:predicates)
+          -> compilePredicates predicates (compile exp context position last effective_axis) True
+      Ast "predicate" [condition,body]
+          -> compilePredicates [condition] (compile body context position last effective_axis) True
+      Ast "append" args
+          -> [| appendText $(listE (map (\x -> compile x context position last effective_axis) args)) |]
+      Ast "call" ((Avar f):args)
+          -> callF f (map (\x -> compile x context position last effective_axis) args)
+      Ast "construction" [Astring tag,Ast "attributes" [],body]
+          -> let ct = litE (StringL tag)
+                 bc = compile body context position last effective_axis
+             in [| [ XElem $ct [] 0 parent_error $bc ] |]
+      Ast "construction" [tag,Ast "attributes" al,body]
+          -> let alc = foldr (\(Ast "pair" [a,v]) r
+                                  -> let ac = compile a context position last effective_axis
+                                         vc = compile v context position last effective_axis
+                                     in [| (qName $ac,showXS $vc) : $r |]) [| [] |] al
+                 ct = compile tag context position last effective_axis
+                 bc = compile body context position last effective_axis
+             in [| [ XElem (qName $ct) $alc 0 parent_error $bc ] |]
+      Ast "let" [Avar var,source,body]
+          -> do s <- compile source context position last effective_axis
+                b <- compile body context position last effective_axis
+                return (AppE (LamE [VarP (mkName var)] b) s)
+      Ast "for" [Avar var,Avar "$",source,body]      -- a for-loop without an index
+          -> let b = compile body [| head $(varE (mkName var)) |] undef2 undef3 ""
+                 f = lamE [varP (mkName var)] [| \r -> $b ++ r |]
+                 s = compile source context position last effective_axis
+             in [| foldr (\x -> $f [x]) [] $s |]
+      Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
+          -> let b = compile body [| head $(varE (mkName var)) |]
+                             [| $(varE (mkName ivar)) |] undef3 ""
+                 f = lamE [varP (mkName var)] (lamE [varP (mkName ivar)] [| \r -> $b ++ r |])
+                 p = maxPosition (Avar ivar) body
+                 ns = if p > 0              -- there is a top-k like restriction
+                      then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
+                      else source
+                 s = compile ns context position last effective_axis
+             in [| foldir (\x i -> $f [x] [XInt i]) [] $s 1 |]
+      Ast "sortTuple" (exp:orderBys)             -- prepare each FLWOR tuple for sorting
+          -> let res = foldl (\r a -> let ac = compile a context position last effective_axis
+                                      in [| $r++[text $ac] |] )
+                             [| [ $(compile exp context position last effective_axis) ] |] orderBys
+             in [| [ $res ] |]
+      Ast "sort" (exp:ordList)                   -- blocking
+          -> let ce = compile exp context position last effective_axis
+                 ordering = foldr (\(Avar ord) r
+                                       -> let asc = if ord == "ascending"
+                                                    then [| True |]
+                                                    else [| False |]
+                                          in [| \(x:xs) (y:ys) -> case compareXSeqs $asc x y of
+                                                                    EQ -> $r xs ys
+                                                                    o -> o |])
+                                  [| \xs ys -> EQ |] ordList
+             in [| concatMap head (sortBy (\(_:xs) (_:ys) -> $ordering xs ys) ($ce::[[XSeq]])) |]
+      _ -> error ("Illegal XQuery: "++(show e))
+
+
+-- The monadic compilePredicates that propagates IO state
+compilePredicatesM :: [Ast] -> Q Exp -> Bool -> Q Exp
+compilePredicatesM [] xs _
+    = [| return $xs |]
+compilePredicatesM ((Aint n):preds) xs _   -- shortcut that improves laziness
+    = compilePredicatesM preds
+            [| [ $xs !! $(litE (IntegerL (toInteger (n-1)))) ] |] True
+compilePredicatesM (pred:preds) xs True    -- top-k like
+    | maxPosition pathPosition pred > 0
+    = compilePredicatesM (pred:preds)
+           [| take $(litE (IntegerL (toInteger (maxPosition pathPosition pred)))) $xs |] False
+compilePredicatesM (pred:preds) xs _
+    | containsLast pred         -- blocking: use only when last() is used in the predicate
+    = [| do let bl = $xs
+                last = length bl
+            vs <- foldir (\x i r -> do vs <- $(compileM pred [| x |] [| [XInt i] |] [| [XInt last] |] "")
+                                       s <- r
+                                       return (if case vs of
+                                                    [XInt k] -> k == i               -- indexing
+                                                    b -> conditionTest b
+                                               then x:s else s))
+                         (return []) $xs 1
+            $(compilePredicatesM preds [| vs |] True) |]
+compilePredicatesM (pred:preds) xs _
+    = [| do vs <- foldir (\x i r -> do vs <- $(compileM pred [| x |] [| [XInt i] |] undef3 "")
+                                       s <- r
+                                       return (if case vs of
+                                                    [XInt k] -> k == i               -- indexing
+                                                    b -> conditionTest b
+                                               then x:s else s))
+                         (return []) $xs 1
+            $(compilePredicatesM preds [| vs |] True) |]
+
+
+-- The monadic XQuery compiler; it is like compile but has plumbing to propagate IO state
+compileM :: Ast -> Q Exp -> Q Exp -> Q Exp -> String -> Q Exp
+compileM e context position last effective_axis
+  = case e of
+      Avar "." -> [| return [ $context :: XTree ] |]
+      Avar v -> let x = varE (mkName v)
+                in [| return ($x :: XSeq) |]
+      Aint n -> let x = litE (IntegerL (toInteger n))
+                in [| return [ XInt $x ] |]
+      Afloat n -> let x = litE (RationalL (toRational n))
+                  in [| return [ XFloat $x ] |]
+      Astring s -> let x = litE (StringL s)
+                   in [| return [ XText $x ] |]
+      -- for non-IO XQuery, use the regular compile
+      Ast "nonIO" [u] -> [| return $(compile u context position last effective_axis) |]
+      Ast "context" [v,Astring dp,body]
+          -> [| do vs <- $(compileM v context position last effective_axis)
+                   foldr (\x r -> (liftM2 (++)) $(compileM body [| x |] position last dp) r)
+                         (return []) vs |]
+      Ast "call" [Avar "position"]
+          -> [| return $position |]
+      Ast "call" [Avar "last"]
+          -> [| return $last |]
+      Ast "child_step" [tag, Avar "."]
+          | effective_axis /= ""
+          -> compileM (Ast effective_axis [tag, Avar "."]) context position last ""
+      Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
+          -> let bc = compileM body context position last effective_axis
+                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
+             in [| do vs <- $bc
+                      foldr (\x r -> (liftM2 (++)) $(compilePredicatesM predicates
+                                                         [| descendant_any_with_tagged_children $ts x |] True) r)
+                            (return []) vs |]
+      Ast "step" ((Ast path_step [Astring tag,body]):predicates)
+          |  memV path_step paths
+          -> let bc = compileM body context position last effective_axis
+                 tc = litE (stringL tag)
+             in [| do vs <- $bc
+                      foldr (\x r -> (liftM2 (++)) $(compilePredicatesM predicates
+                                                           [| $(findV path_step paths) $tc x |] True) r)
+                            (return []) vs |]
+      Ast "descendant_any" (body:tags)
+          -> let bc = compileM body context position last effective_axis
+                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
+             in [| do vs <- $bc
+                      return (foldr (\x r -> (descendant_any_with_tagged_children $ts x)++r) [] vs) |]
+      Ast path_step [Astring tag,body]
+          |  memV path_step paths
+          -> let bc = compileM body context position last effective_axis
+                 tc = litE (stringL tag)
+             in [| do vs <- $bc
+                      return (foldr (\x r -> ($(findV path_step paths) $tc x)++r) [] vs) |]
+      Ast "step" (exp:predicates)
+          -> [| do vs <- $(compileM exp context position last effective_axis)
+                   $(compilePredicatesM predicates [| vs |] True) |]
+      Ast "predicate" [condition,body]
+          -> [| do vs <- $(compileM body context position last effective_axis)
+                   $(compilePredicatesM [condition] [| vs |] True) |]
+      Ast "executeSQL" [Avar stmt,args]
+          -> [| do as <- $(compileM args context position last effective_axis)
+                   $(varE (mkName "executeSQL")) $(varE (mkName stmt)) as |]
+      Ast "append" args
+          -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args
+             in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])
+                      [| return (appendText $(listE (map (\(n,_) -> varE n) binds))) |] binds
+      Ast "call" ((Avar f):args)
+          -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args
+             in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])
+                      [| return $(callF f (map (\(n,_) -> varE n) binds)) |] binds
+      Ast "construction" [Astring tag,Ast "attributes" [],body]
+          -> let ct = litE (StringL tag)
+                 bc = compileM body context position last effective_axis
+             in [| do b <- $bc
+                      return [ XElem $ct [] 0 parent_error b ] |]
+      Ast "construction" [tag,Ast "attributes" al,body]
+          -> let alc = foldr (\(Ast "pair" [a,v]) r
+                                  -> [| do ac <- $(compileM a context position last effective_axis)
+                                           vc <- $(compileM v context position last effective_axis)
+                                           s <- $r
+                                           return ((qName ac,showXS vc):s) |]) [| return [] |] al
+                 ct = compileM tag context position last effective_axis
+                 bc = compileM body context position last effective_axis
+             in [| do a <- $alc
+                      c <- $ct
+                      b <- $bc
+                      return [ XElem (qName c) a 0 parent_error b ] |]
+      Ast "let" [Avar var,source,body]
+          -> [|  $(compileM source context position last effective_axis)
+                 >>= $(lamE [varP (mkName var)] (compileM body context position last effective_axis)) |]
+      Ast "for" [Avar var,Avar "$",source,body]      -- a for-loop without an index
+          -> let b = compileM body [| head $(varE (mkName var)) |] undef2 undef3 ""
+                 f = lamE [varP (mkName var)] [| (liftM2 (++)) $b |]
+                 s = compileM source context position last effective_axis
+             in [| do vs <- $s
+                      foldr (\x -> $f [x]) (return []) vs |]
+      Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
+          -> let b = compileM body [| head $(varE (mkName var)) |]
+                             [| $(varE (mkName ivar)) |] undef3 ""
+                 f = lamE [varP (mkName var)] (lamE [varP (mkName ivar)] [| (liftM2 (++)) $b |])
+                 p = maxPosition (Avar ivar) body
+                 ns = if p > 0              -- there is a top-k like restriction
+                      then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
+                      else source
+                 s = compileM ns context position last effective_axis
+             in [| do vs <- $s
+                      foldir (\x i -> $f [x] [XInt i]) (return []) vs 1 |]
+      Ast "sortTuple" (exp:orderBys)             -- prepare each FLWOR tuple for sorting
+          -> let vs = compileM exp context position last effective_axis
+                 res = foldl (\r a -> [| do ac <- $(compileM a context position last effective_axis)
+                                            s <- $r
+                                            return (s++[text ac]) |] )
+                             [| do v <- $vs; return [ v ] |] orderBys
+             in [| return $res |]
+      Ast "sort" (exp:ordList)                   -- blocking
+          -> let ce = compileM exp context position last effective_axis
+                 ordering = foldr (\(Avar ord) r
+                                       -> let asc = if ord == "ascending"
+                                                    then [| True |]
+                                                    else [| False |]
+                                          in [| \(x:xs) (y:ys) -> case compareXSeqs $asc x y of
+                                                                    EQ -> $r xs ys
+                                                                    o -> o |])
+                                  [| \xs ys -> EQ |] ordList
+             in [| do c <- $ce
+                      return (concatMap head (sortBy (\(_:xs) (_:ys) -> $ordering xs ys) (c::[[XSeq]]))) |]
+      _ -> error ("Illegal XQuery: "++(show e))
+
+
+-- functions that need IO interaction (document reader, DB access, etc)
+ioSources :: [ String ]
+ioSources = ["executeSQL","doc","fn:doc","sql","fn:sql","publish","fn:publish"]
+
+
+-- collect all input documents and assign them a unique number
+pullIOSources :: Ast -> Int -> (Ast, Int, [(String, Ast)])
+pullIOSources query count
+    = case query of
+             Ast "call" [Avar nm,file]
+                 | elem nm ["doc","fn:doc"]
+                 -> (Avar ("_doc"++(show count)), count+1, [("_doc"++(show count),file)])
+             Ast "call" [Avar nm,sql]
+                 | elem nm ["sql","fn:sql"]
+                 -> (Ast "executeSQL" [Avar ("_sql"++(show count)),Ast "call" [Avar "empty"]], count+1,
+                     [("_sql"++(show count),Ast "prepareSQL" [sql])])
+             Ast "call" [Avar nm,sql,args]
+                 | elem nm ["sql","fn:sql"]
+                 -> (Ast "executeSQL" [Avar ("_sql"++(show count)),args], count+1,
+                     [("_sql"++(show count),Ast "prepareSQL" [sql])])
+             Ast n args
+                 -> let (s,c,ns) = foldr (\a r c -> let (e,c1,n1) = pullIOSources a c
+                                                        (s,c2,n2) = r c1
+                                                    in (e:s,c2,union n1 n2))
+                                         (\c -> ([],c,[])) args count
+                    in (Ast n s,c,ns)
+             _ -> (query,count,[])
+    where union xs ((n,s):ys) = (n,foldr(\(m,d) r -> if s==d then Avar m else r) s xs):(union xs ys)
+          union xs [] = xs
+
+
+-- true if there is no need to lift to the IO monad
+noIO :: Ast -> Bool
+noIO (Ast nm _) | elem nm ioSources = False
+noIO (Ast n args) = all noIO args
+noIO _ = True
+
+
+liftIOSources :: Ast  -> (Ast, [(String, Ast)])
+liftIOSources query
+    = let (ast,_,ns) = pullIOSources query 0
+          f x = case x of
+                  Ast nm _ | elem nm ["attributes"] -> x
+                  Ast _ _ | noIO x -> Ast "nonIO" [x]
+                  _ -> case x of
+                         Ast "call" ((Avar nm):args)
+                             -> Ast "call" ((Avar nm):(map f args))
+                         Ast n args -> Ast n (map f args)
+                         _ -> x
+      in (f ast,ns)
+
+
+-- optimize and compile an AST (unlifted)
+compileAst :: Ast -> Q Exp
+compileAst ast = compile (optimize ast) undef1 undef2 undef3 ""
+
+
+-- optimize and compile an AST (IO lifted)
+compileAstM :: Ast -> Q Exp
+compileAstM ast = compileM (optimize ast) undef1 undef2 undef3 ""
+
+
+-- compile an XQuery AST that reads XML documents
+compileQuery :: [Ast] -> Q Exp
+compileQuery ((Ast "function" ((Avar f):b:args)):xs)
+    = let lvars = case args of
+                    [Astring a] -> [varP (mkName a)]
+                    _ -> [tupP (map (\(Avar a) -> varP (mkName a)) args)]
+      in letE [valD (varP (mkName f)) (normalB (lamE lvars (compileAst b))) []]
+              (compileQuery xs)
+compileQuery ((Ast "variable" [Avar v,u]):xs)
+    = letE [valD (varP (mkName v)) (normalB (compileAst u)) []]
+           (compileQuery xs)
+compileQuery [query]
+    = let (ast,ns) = liftIOSources (optimize query)
+          code = compileM ast undef1 undef2 undef3 ""
+      in foldl (\r (n,e) -> let d = lamE [varP (mkName n)] r
+                            in case e of
+                                 Avar m -> [| $d $(varE (mkName m)) |]
+                                 Ast "prepareSQL" [Astring sql]
+                                     -> [| ($(varE (mkName "prepareSQL"))
+                                                    $(varE (mkName "_db"))
+                                                    $(litE (StringL sql))) >>= $d |]
+                                 _ -> [| do let [XText f] = $(compileAst e)
+                                            doc <- readFile f
+                                            $d [materialize (parseDocument doc)] |])
+               [| $code |] ns
+
+
+-- Debugging: display the AST and the Haskell code of an input XQuery
+cq :: String -> IO ()
+cq query = do putStrLn "Abstract Syntax Tree:"
+              let ast = parse (scan query)
+              putStrLn (show ast)
+              let opt = optimize (last ast)
+              putStrLn "Optimized AST:"
+              putStrLn (show opt)
+              --putStrLn "Haskell Code:"
+              --let code = compileQuery ast
+              --runQ code >>= putStrLn.pprint
+
+
+-- | Run an XQuery expression that does not read XML documents.
+-- When evaluated, it returns XSeq.
+xe :: String -> Q Exp
+xe query = compileAst (last (parse (scan query)))
+
+
+-- | Run an XQuery that reads XML documents.
+-- When evaluated, it returns IO XSeq.
+xq :: String -> Q Exp
+xq query = compileQuery (parse (scan query))
+
+
+-- | Run an XQuery that reads XML documents and queries databases.
+-- When evaluated, it returns (IConnection conn) => conn -> IO XSeq.
+xqdb :: String -> Q Exp
+xqdb query = lamE [varP (mkName "_db")] (compileQuery (parse (scan query)))
diff --git a/Text/XML/HXQ/DB.hs b/Text/XML/HXQ/DB.hs
new file mode 100644
--- /dev/null
+++ b/Text/XML/HXQ/DB.hs
@@ -0,0 +1,503 @@
+{-------------------------------------------------------------------------------------
+-
+- Database connectivity using HDBC
+- Programmer: Leonidas Fegaras
+- Email: fegaras@cse.uta.edu
+- Web: http://lambda.uta.edu/
+- Creation: 05/12/08, last update: 07/24/08
+- 
+- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
+- This material is provided as is, with absolutely no warranty expressed or implied.
+- Any use is at your own risk. Permission is hereby granted to use or copy this program
+- for any purpose, provided the above notices are retained on all copies.
+-
+--------------------------------------------------------------------------------------}
+
+
+module Text.XML.HXQ.DB where
+
+import System.IO.Unsafe
+import Char(isSpace,toLower)
+import Control.Monad.State
+import Database.HDBC
+import Text.XML.HXQ.DBConnect
+import Text.XML.HXQ.XTree
+import XMLParse(XMLEvent(..),parseDocument)
+import HXML(AttList)
+import Text.XML.HXQ.Parser
+
+
+sql2xml :: SqlValue -> XTree
+sql2xml value =
+    case value of
+      SqlString s -> XText s
+      SqlByteString bs -> XText (show bs)
+      SqlWord32 n -> XInt (fromEnum n)
+      SqlWord64 n -> XInt (fromEnum n)
+      SqlInt32 n -> XText (show n)
+      SqlInt64 n -> XText (show n)
+      SqlInteger n -> XInt (fromEnum n)
+      SqlChar c -> XText [c]
+      SqlBool b -> XBool b
+      SqlDouble n -> XText (show n)
+      SqlRational n -> XText (show n)
+      SqlEpochTime n -> XText (show n)
+      SqlTimeDiff n -> XText (show n)
+      SqlNull -> XText ""
+
+
+xml2sql :: XTree -> SqlValue
+xml2sql e =
+    case e of
+      XText s -> SqlString s
+      XInt n -> SqlInteger (toInteger n)
+      XFloat n -> SqlString (show n)
+      XBool n -> SqlBool n
+      XElem n _ _ _ [x] -> xml2sql x
+      _ -> error ("Cannot convert "++show e++" into sql")
+
+
+perror = error "constructed elements have no parent"
+
+
+executeSQL :: Statement -> XSeq -> IO XSeq
+executeSQL stmt args
+    = do n <- handleSqlError (execute stmt (map xml2sql args))
+         result <- handleSqlError (fetchAllRowsAL stmt)
+         return (map (\x -> XElem "row" [] 0 perror (map (\(s,v) -> XElem s [] 0 perror [sql2xml v]) x)) result)
+
+
+prepareSQL :: (IConnection conn) => conn -> String -> IO Statement
+prepareSQL db sql = handleSqlError (prepare db sql)
+
+
+{---------------------------------------------------------------------------------------
+-- extract the structural summary of an XML file that contains statistics
+----------------------------------------------------------------------------------------}
+
+
+-- structural summary: tag   id  max#      hasText children
+data SSnode = SSnode String !Int !Int !Int !Bool   [SSnode]
+            deriving (Eq,Show)
+
+
+insertSS :: String -> [SSnode] -> State Int (Int,SSnode,[SSnode])
+insertSS tag ((SSnode n i j l b ts):s)
+    | n == tag
+    = return (i,SSnode n i j (l+1) b ts,s)
+insertSS tag (x:xs)
+    = do (i,t,ts) <- insertSS tag xs
+         return (i,t,x:ts)
+insertSS tag []
+    = do count <- get
+         put (count+1)
+         return (count+1,SSnode tag (count+1) 1 1 False [],[])
+
+
+insSS :: String -> [SSnode] -> State Int [SSnode]
+insSS tag ns = do (k,t,s) <- insertSS tag ns
+                  return (t:s)
+
+
+getSS :: [XMLEvent] -> [SSnode] -> State Int [SSnode]
+getSS ((EmptyEvent n atts):xs) rs
+    = getSS ((StartEvent n atts):(EndEvent n):xs) rs
+getSS ((StartEvent n atts):xs) ((SSnode m i j l b ns):rs)
+    = do (k,SSnode m' i' j' l' b' ks,ts) <- insertSS n ns
+         as <- foldM (\r (a,_) -> insSS ('@':a) r) ks atts
+         getSS xs (reset(SSnode m' i' j' l' b' as):(SSnode m i j l b ts):rs)
+    where r (SSnode m i j _ b ts) = SSnode m i j 0 b ts
+          reset (SSnode m i j l b ts) = SSnode m i j l b (map r ts)
+getSS ((EndEvent n):xs) (t:(SSnode m i j l b ns):rs)
+    = getSS xs ((SSnode m i j l b (set t:ns):rs))
+    where s (SSnode m i j l b ts) = SSnode m i (max j l) 0 b ts
+          set (SSnode m i j l b ts) = SSnode m i j l b (map s ts)
+getSS ((TextEvent t):xs) ((SSnode m i j l False ns):rs)
+    | any (not . isSpace) t
+    = getSS xs ((SSnode m i j l True ns):rs)
+getSS (_:xs) rs = getSS xs rs
+getSS [] rs = return rs
+
+
+{---------------------------------------------------------------------------------------
+-- Derive a good relational schema based on the structural summary (using hybrid inlining)
+----------------------------------------------------------------------------------------}
+
+
+type Path = [Tag]
+
+
+data Table = Table String Path Bool [Table]
+           | Column String Path
+           deriving (Show,Read)
+
+
+printPath :: Path -> String
+printPath [] = ""
+printPath [p] = p
+printPath (p:ps) = printPath ps++"/"++p
+
+
+pathCons p ps = if p=="root" then ps else p:ps
+
+
+schema :: SSnode -> String -> [String] -> [Table]
+schema (SSnode n i _ (-1) _ ts) prefix path
+    = [ Table (prefix++show i) (pathCons n path) True
+              ((reverse (concatMap (\t -> schema t prefix []) ts))
+               ++[ Column "value" [] ]) ]
+schema (SSnode n i j _ _ []) prefix path
+    | j == 1 || head n == '@'
+    = [ Column (prefix++show i) (pathCons n path) ]
+schema (SSnode n i 1 _ _ ts) prefix path
+    = concatMap (\t -> schema t prefix (pathCons n path)) ts
+schema (SSnode n i _ _ b ts) prefix path
+    = [ Table (prefix++show i) (pathCons n path) False
+              ((reverse (concatMap (\t -> schema t prefix []) ts))
+              ++(if b && all (\(SSnode x _ _ _ _ _)-> head x == '@') ts
+                 then [ Column "value" [] ] else [])) ]
+
+
+fixSS :: SSnode -> SSnode
+fixSS (SSnode n i j l True ts)
+    | any (\(SSnode x _ _ _ _ _)-> head x /= '@') ts
+    = SSnode n i j (-1) True (filter (\(SSnode x _ _ _ _ _)-> head x == '@') ts)
+fixSS (SSnode n i j l b ts)
+    = SSnode n i j l b (map fixSS ts)
+
+
+deriveSchema :: String -> String -> IO Table
+deriveSchema file prefix
+    = do doc <- readFile file
+         let ts = parseDocument doc
+             d = getSS ts [SSnode "root" 1 1 1 False []]
+             [SSnode _ _ _ _ _ [t]] = evalState d 1
+             nt@(SSnode m i j l b s) = fixSS t
+         return (Table prefix [] False (reverse (schema (SSnode m i 2 l b s) prefix [])))
+
+
+relationalSchema :: Table -> String -> [String]
+relationalSchema (Table n path b ts) parent
+    = ("create table "++n++" (      /* "++printPath path
+       ++(if b then " (mixed content)" else "")++" */\n"
+       ++n++"_id int,\n"
+       ++(if parent /= "" then (n++"_parent int references "++parent++"("++parent++"_id),\n") else "")
+       ++(concat [ m++" varchar,    /* "++printPath p++" */\n" | Column m p <- ts ])
+       ++"primary key ("++n++"_id))\n")
+      :[ s | t@(Table _ _ _ _) <- ts, s <- relationalSchema t n ]
+
+
+getTableNames :: Table -> [String]
+getTableNames (Table n _ _ ts) = n:(concatMap getTableNames ts)
+getTableNames _ = []
+
+
+initializeDB :: (IConnection conn) => conn -> IO ()
+initializeDB db
+    = do tables <- getTables db
+         if elem "HXQCatalog" tables
+            then return ()
+            else do let s = "create table HXQCatalog ( name varchar primary key, path varchar, summary varchar )"
+                    handleSqlError (run db s [])
+                    commit db
+
+
+createSchema :: (IConnection conn) => conn -> String -> String -> IO Table
+createSchema db file name
+    = do initializeDB db
+         stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")
+         _ <- handleSqlError (execute stmt  [SqlString name])
+         result <- handleSqlError (fetchAllRowsAL stmt)
+         if length result > 0
+            then do let [[(_,SqlString s)]] = result
+                        summary = (read s)::Table
+                        tables = getTableNames summary
+                    _ <- mapM (\t -> handleSqlError (run db ("drop table if exists "++t) [])) tables
+                    _ <- handleSqlError (run db "delete from HXQCatalog where name = ?" [SqlString name])
+                    commit db
+            else return ()
+         t <- deriveSchema file name
+         let schema = relationalSchema t ""
+         -- mapM putStrLn schema
+         _ <- handleSqlError (run db "insert into HXQCatalog values (?,?,?)"
+                                      [SqlString name, SqlString file, SqlString (show t)])
+         _ <- mapM (\s -> handleSqlError (run db s [])) schema
+         commit db
+         return t
+
+
+findSchema :: (IConnection conn) => conn -> String -> IO Table
+findSchema db name
+    = do initializeDB db
+         stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")
+         _ <- handleSqlError (execute stmt  [SqlString name])
+         result <- handleSqlError (fetchAllRowsAL stmt)
+         if length result == 1
+            then let [[(_,SqlString s)]] = result
+                 in return ((read s)::Table)
+            else error ("Schema "++name++" doesn't exist")
+
+
+{---------------------------------------------------------------------------------------
+-- Populate the database from the XML file and its derived structural summary
+----------------------------------------------------------------------------------------}
+
+
+findPath :: [Table] -> [String] -> Int -> Maybe (Int,Table)
+findPath (t@(Table _ p _ s):ts) path _ | p == path = Just ((length s)-1,t)
+findPath (t@(Column _ p):ts) path n | p == path = Just (n,t)
+findPath ((Table _ _ _ _):ts) path n = findPath ts path n
+findPath (_:ts) path n = findPath ts path (n+1)
+findPath [] _ _ = Nothing
+
+
+populate :: [XMLEvent] -> [Table] -> Int -> [[String]] -> [(Int,String)]
+populate ((EmptyEvent tag atts):xs) ts n ps
+    = populate ((StartEvent tag atts):(EndEvent tag):xs) ts n ps
+populate (x@(StartEvent tag atts):xs) ((t@(Table n path _ s)):ts) _ (p:ps)
+    = case findPath s (tag:p) 0 of
+        Just (n,nt@(Table m _ True as))
+            -> (-1,m):(popAtts atts as ++ showXTree xs 1 "")
+               where showXTree ((EmptyEvent tag atts):xs) i s
+                         = showXTree xs i (s++"<"++tag++showAL atts++"/>")
+                     showXTree ((StartEvent tag atts):xs) i s
+                         = showXTree xs (i+1) (s++"<"++tag++showAL atts++">")
+                     showXTree ((EndEvent tag):xs) i s
+                         = if i==1 then (n,s):(-2,m):(populate xs (t:ts) n (p:ps))
+                           else showXTree xs (i-1) (s++"</"++tag++">")
+                     showXTree ((TextEvent text):xs) i s = showXTree xs i (s++text)
+                     showXTree (_:xs) i s = showXTree xs i s
+        Just (n,nt@(Table m _ _ as))
+            -> (-1,m):((popAtts atts as)++(populate xs (nt:t:ts) n ([]:p:ps)))
+        Just (n,nt)
+            -> populate xs (nt:t:ts) n ((tag:p):ps)
+        Nothing -> populate xs (t:ts) 0 ((tag:p):ps)
+      where popAtts ((a,v):as) ks
+                = let Just(m,_) = findPath ks ['@':a] 0
+                  in (m,v):(popAtts as ks)
+            popAtts [] _ = []
+populate ((EndEvent tag):xs) ((t@(Table n path _ s)):ts) _ ([]:ps)
+    = (-2,n):populate xs ts 0 ps
+populate ((EndEvent tag):xs) ((Column m path):ts) n (p:ps)
+    = populate xs ts 0 (tail p:ps)
+populate ((EndEvent text):xs) ts _ (p:ps)
+    = populate xs ts 0 (tail p:ps)
+populate ((TextEvent text):xs) ts n ps
+    | any (not . isSpace) text
+    = (n,text):populate xs ts n ps
+populate (x:xs) ts n ps
+    = populate xs ts n ps
+populate [] ts n ps = []
+
+
+insert :: (IConnection conn) => conn -> [(Int,String)] -> [(String,Int,Statement)] -> IO ()
+insert db xs stmts = let (s,_,_,_) = m xs 0 0 in s
+    where m ((-1,m):xs) i p = let (s,el,xs',i') = ml xs (i+1) i
+                              in (s >> insertTuple m el i p,[],xs',i')
+          m ((k,m):xs) i p = (return (),[(k,m)],xs,i)
+          ml [] i p = (return (),[],[],i)
+          ml ((-2,m):xs) i p = (return (),[],xs,i)
+          ml xs i p = let (s,el,xs',i') = m xs i p
+                          (s',el',xs'',i'') = ml xs' i' p
+                      in (s >> s',el++el',xs'',i'')
+          find x xs = foldr (\(a,v) r -> if x==a then v else r) "\NUL" xs
+          insertTuple m e i p
+              = let (len,stmt) = foldr (\(a,l,s) r -> if m==a then (l,s) else r) (error "") stmts
+                    tuple = map (\c -> find c e) [0..len]
+                    lift x = if x=="\NUL" then SqlNull else SqlString x
+                in do _ <- handleSqlError (execute stmt
+                                           (if i==0
+                                            then SqlInteger i:(map lift tuple)
+                                            else SqlInteger i:SqlInteger p:(map lift tuple)))
+                      if mod i 100 == 99 then commit db else return ()
+                      return ()
+
+
+-- | Store an XML document into the database under the given name.
+shred :: (IConnection conn) => conn -> String -> String -> IO ()
+shred db file name
+    = do let prefix = map toLower name
+         let tableStmt (Table n _ _ ts)
+                 = do let len = length[ 1 | Column _ _ <- ts]-1
+                      stmt <- handleSqlError (prepare db ("insert into "++n++" values ("
+                                                          ++(if n==prefix then "" else "?,")++"?"
+                                                          ++(concatMap (\_ -> ",?") [0..len])++")"))
+                      l <- mapM tableStmt ts
+                      return ((n,len,stmt):(concat l))
+             tableStmt _ = return []
+         t <- createSchema db file prefix
+         stmts <- tableStmt t
+         doc <- readFile file
+         let ts = parseDocument doc
+         let ic = (-1,prefix):(populate ts [t] 0 [[]] ++ [(-2,prefix)])
+         insert db ic stmts
+         commit db
+         return ()
+
+
+-- | Create a secondary index on tagname for the shredded document under the given name..
+createIndex :: (IConnection conn) => conn -> String -> String -> IO ()
+createIndex db name tagname
+    = do let prefix = map toLower name
+         table <- findSchema db name
+         let indexes = getIndexes "" table
+         _ <- if null indexes
+              then error ("there is no tagname: "++tagname)
+              else mapM (\(t,c) -> do stmt <- handleSqlError (prepare db ("create index "++t++"_"++c++" on "++t++" ("++c++")"))
+                                      handleSqlError (execute stmt [])) indexes
+         commit db
+         return ()
+    where getIndexes _ (Table n _ _ ts) = concatMap (getIndexes n) ts
+          getIndexes table (Column n path) | (head path)==tagname = [(table,n)]
+          getIndexes _ _ = []
+
+
+{----------------------------------------------------------------------------------------------------
+--  Convert XQuery to SQL
+----------------------------------------------------------------------------------------------------}
+
+
+publishES :: [String] -> [String] -> String
+publishES (p:ps) xs
+    | head p == '@'
+    = "attribute "++(tail p)++" {"++publishES ps xs++"}"
+publishES (p:ps) xs
+    = "<"++p++">{"++publishES ps xs++"}</"++p++">"
+publishES [] [x] = x
+publishES [] (x:xs) = x++","++publishES [] xs
+
+
+publishS :: Table -> String -> String
+publishS (Table n path b ts) "error"
+    = "for $"++n++" in SQL(select(),from($"++n++"),true()) return "
+      ++publishES (reverse path) (map (\t -> publishS t n) ts)
+publishS (Table n path b ts) parent
+    = "for $"++n++" in SQL(select(),from($"++n++"),$"++n++"/"++n++"_parent eq $"
+      ++parent++"/"++parent++"_id) return "
+      ++publishES (reverse path) (map (\t -> publishS t n) ts)
+publishS (Column n path) parent
+    = publishES (reverse path) ["$"++parent++"/"++n++"/text()"]
+
+
+publishTable :: Table -> String
+publishTable table = "<root>{" ++ publishS table "error" ++ "}</root>"
+
+
+sqlComparisson = [("=","="),("eq","="),("<=","<="),(">=",">="),("!=","!="),(">",">"),
+                  ("<","<"),("ne","!="),("gt",">"),("lt","<"),("ge",">="),("le","<=")]
+
+sqlBoolean = [("and","and"),("or","or")]
+
+
+-- Is this an SQL predicate?
+sqlPredicate :: [String] -> Ast -> Bool
+sqlPredicate tables e
+    = case e of
+        Ast "child_step" [Astring c,Avar v]
+            -> elem v tables
+        Ast "construction" [_,_,Ast "append" [x]]
+            -> sqlPredicate tables x
+        Ast "call" [Avar "text",x]
+            -> sqlPredicate tables x
+        Ast "call" [Avar cmp,x,y]
+            | any (\(f,_) -> f==cmp) sqlComparisson
+            -> (sqlExpr x) && (sqlExpr y)
+        Ast "call" [Avar cmp,x,y]
+            | any (\(f,_) -> f==cmp) sqlBoolean
+            -> (sqlPredicate tables x) && (sqlPredicate tables y)
+        _ -> False
+      where sqlExpr e
+                = case e of
+                    Astring s -> True
+                    Aint n -> True
+                    Ast "child_step" [Astring c,Avar v]
+                        -> elem v tables
+                    Ast "construction" [_,_,Ast "append" [x]]
+                        -> sqlExpr x
+                    Ast "call" [Avar "text",x]
+                        -> sqlExpr x
+                    _ -> False
+
+
+-- Convert a predicate AST to an SQL predicate that uses the tables
+predToSQL :: [String] -> Ast -> (String,[Ast])
+predToSQL tables e
+    = case e of
+        Ast "child_step" [Astring c,Avar v]
+            -> if elem v tables
+               then ("",[])
+               else error ("Cannot convert to an SQL predicate: "++show e)
+        Ast "construction" [_,_,Ast "append" [x]]
+            -> predToSQL tables x
+        Ast "call" [Avar "text",x]
+            -> predToSQL tables x
+        Ast "call" [Avar cmp,x,y]
+            | any (\(f,_) -> f==cmp) sqlComparisson
+            -> let (nx,vx) = expToSQL tables x
+                   (ny,vy) = expToSQL tables y
+               in if nx == ""
+                  then (ny,vx)
+                  else if ny == ""
+                       then (nx,vy)
+                       else (nx ++ " " ++ snd (head (filter (\(f,_) -> f==cmp) sqlComparisson)) ++ " " ++ ny,vx++vy)
+        Ast "call" [Avar cmp,x,y]
+            | any (\(f,_) -> f==cmp) sqlBoolean
+            -> let (nx,vx) = predToSQL tables x
+                   (ny,vy) = predToSQL tables y
+               in if nx == ""
+                  then (ny,vy)
+                  else if ny == ""
+                       then (nx,vx)
+                       else (nx ++ " " ++ snd (head (filter (\(f,_) -> f==cmp) sqlBoolean)) ++ " " ++ ny,vx++vy)
+        _ -> error ("Cannot convert to an SQL predicate: "++show e)
+      where expToSQL tables e
+                = case e of
+                    Astring s -> ("\'"++s++"\'",[])
+                    Aint n -> (show n,[])
+                    Ast "child_step" [Astring c,Avar v]
+                        -> if elem v tables
+                           then (v++"."++c,[])
+                           else ("?",[e])
+                    Ast "construction" [_,_,Ast "append" [x]]
+                        -> expToSQL tables x
+                    Ast "call" [Avar "text",x]
+                        -> expToSQL tables x
+                    _ -> ("?",[e])
+
+
+-- Convert an AST to an SQL query
+makeSQL :: [Ast] -> Ast -> [Ast] -> (String,[Ast])
+makeSQL tables pred cols
+    = let tnames = [ x | Avar x <- tables ]
+          ts = combine tnames
+          cs = combine [ x | Avar x <- cols ]
+          vars (Ast n args) = concatMap vars args
+          vars (Avar v) | not (elem v tnames) = [v]
+          vars _ = []
+          combine [] = ""
+          combine [x] = x
+          combine (x:xs) = x++", "++combine xs
+      in if pred == Ast "call" [Avar "true"]
+         then (if null cs
+               then "select * from "++ts
+               else "select "++cs++" from "++ts,[])
+         else let (p,args) = predToSQL tnames pred
+              in (if null cs
+                  then "select * from "++ts++" where "++p
+                  else "select "++cs++" from "++ts++" where "++p,args)
+
+
+{-# NOINLINE publishXmlDoc #-}
+-- get an XML document stored in a relational database
+publishXmlDoc :: FilePath -> String -> Ast
+publishXmlDoc filepath name
+    = let query = unsafePerformIO (publishWrapper filepath name)
+          [ast] = parse (scan query)
+      in ast
+    where publishWrapper filepath name
+              = do let prefix = map toLower name
+                   db <- connect filepath
+                   table <- findSchema db prefix
+                   let query = publishTable table
+                   -- disconnect db
+                   return query
diff --git a/Text/XML/HXQ/DBConnect.hs b/Text/XML/HXQ/DBConnect.hs
new file mode 100644
--- /dev/null
+++ b/Text/XML/HXQ/DBConnect.hs
@@ -0,0 +1,26 @@
+{-------------------------------------------------------------------------------------
+-
+- HDBC driver. Currently, Sqlite3.
+- Programmer: Leonidas Fegaras
+- Email: fegaras@cse.uta.edu
+- Web: http://lambda.uta.edu/
+- Creation: 05/30/08, last update: 07/24/08
+- 
+- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
+- This material is provided as is, with absolutely no warranty expressed or implied.
+- Any use is at your own risk. Permission is hereby granted to use or copy this program
+- for any purpose, provided the above notices are retained on all copies.
+-
+--------------------------------------------------------------------------------------}
+
+
+module Text.XML.HXQ.DBConnect where
+
+
+import Database.HDBC.Sqlite3
+
+
+
+-- | Connect to the relational database in filepath using the HDBC Sqlite3 driver
+connect :: FilePath -> IO Connection
+connect filepath = connectSqlite3 filepath
diff --git a/Text/XML/HXQ/Interpreter.hs b/Text/XML/HXQ/Interpreter.hs
new file mode 100644
--- /dev/null
+++ b/Text/XML/HXQ/Interpreter.hs
@@ -0,0 +1,406 @@
+{-------------------------------------------------------------------------------------
+-
+- The XQuery Interpreter
+- Programmer: Leonidas Fegaras
+- Email: fegaras@cse.uta.edu
+- Web: http://lambda.uta.edu/
+- Creation: 03/22/08, last update: 07/24/08
+- 
+- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
+- This material is provided as is, with absolutely no warranty expressed or implied.
+- Any use is at your own risk. Permission is hereby granted to use or copy this program
+- for any purpose, provided the above notices are retained on all copies.
+-
+--------------------------------------------------------------------------------------}
+
+
+{-# OPTIONS_GHC -fth -fglasgow-exts #-}
+
+
+module Text.XML.HXQ.Interpreter where
+
+import Control.Monad
+import List(sortBy)
+import XMLParse(parseDocument)
+import System.Console.Readline
+import Database.HDBC
+import Text.XML.HXQ.Parser
+import Text.XML.HXQ.XTree
+import Text.XML.HXQ.Optimizer
+import Text.XML.HXQ.Compiler
+import Text.XML.HXQ.DB
+
+
+-- system functions (=, concat, etc)
+systemFunctions :: [(String,Int,[XSeq]->XSeq)]
+systemFunctions = $(iFunctions)
+
+
+-- XPath step functions (child, descendant, etc)
+pathFunctions :: [(String,Tag->XTree->XSeq)]
+pathFunctions = $(pFunctions)
+
+
+-- run-time bindings of FLOWR variables
+type Environment = [(String,XSeq)]
+
+
+-- a user-defined function is (fname,parameters,body)
+type Functions = [(String,[String],Ast)]
+
+
+undefv1 = error "Undefined XQuery context (.)"
+undefv2 = error "Undefined position()"
+undefv3 = error "Undefined last()"
+
+
+
+-- Each XPath predicate must calculate position() and last() from its input XSeq
+-- if last() is used, then the evaluation is blocking (need to store the whole input XSeq)
+applyPredicates :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> XSeq
+applyPredicates [] xs _ _ _ = xs
+applyPredicates ((Aint n):preds) xs _ env fncs   -- shortcut that improves laziness
+    = applyPredicates preds [xs !! (n-1)] True env fncs
+applyPredicates (pred:preds) xs True env fncs    -- top-k like
+    | maxPosition pathPosition pred > 0
+    = applyPredicates (pred:preds) (take (maxPosition pathPosition pred) xs) False env fncs
+applyPredicates (pred:preds) xs _ env fncs
+    | containsLast pred         -- blocking: use only when last() is used in the predicate
+    = let last = length xs
+      in applyPredicates preds
+             (foldir (\x i r -> case eval pred x i last "" env fncs of
+                                  [XInt k] -> if k == i then x:r else r               -- indexing
+                                  b -> if conditionTest b then x:r else r) [] xs 1) True env fncs
+applyPredicates (pred:preds) xs _ env fncs
+    = applyPredicates preds
+          (foldir (\x i r -> case eval pred x i undefv3 "" env fncs of
+                               [XInt k] -> if k == i then x:r else r               -- indexing
+                               b -> if conditionTest b then x:r else r) [] xs 1) True env fncs
+
+
+-- The XQuery interpreter
+-- context: context node (XPath .)
+-- position: the element position in the parent sequence (XPath position())
+-- last: the length of the parent sequence (XPath last())
+-- effective_axis: the XPath axis in /axis::tag(exp)
+--        (eg, the effective axis of //(A | B) is "descendant_step"
+-- env: contains FLOWR variable bindings
+-- fncs: user-defined functions
+eval :: Ast -> XTree -> Int -> Int -> String -> Environment -> Functions -> XSeq
+eval e context position last effective_axis env fncs
+  = case e of
+      Avar "." -> [ context ]
+      Avar v -> findV v env
+      Aint n -> [ XInt n ]
+      Afloat n -> [ XFloat n ]
+      Astring s -> [ XText s ]
+      Ast "context" [v,Astring dp,body]
+          -> foldr (\x r -> (eval body x position last dp env fncs)++r)
+                   [] (eval v context position last effective_axis env fncs)
+      Ast "call" [Avar "position"] -> [XInt position]
+      Ast "call" [Avar "last"] -> [XInt last]
+      Ast "child_step" [tag, Avar "."]
+          |  effective_axis /= ""
+          -> eval (Ast effective_axis [tag, Avar "."]) context position last "" env fncs
+      Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
+          -> let ts = map (\(Avar tag) -> tag) tags
+             in foldr (\x r -> (applyPredicates predicates (descendant_any_with_tagged_children ts x) True env fncs)++r)
+                      [] (eval body context position last effective_axis env fncs)
+      Ast "step" ((Ast path_step [Astring tag,body]):predicates)
+          |  memV path_step pathFunctions
+          -> foldr (\x r -> (applyPredicates predicates ((findV path_step pathFunctions) tag x) True env fncs)++r)
+                   [] (eval body context position last effective_axis env fncs)
+      Ast "descendant_any" (body:tags)
+          -> let ts = map (\(Avar tag) -> tag) tags
+             in foldr (\x r -> (descendant_any_with_tagged_children ts x)++r)
+                      [] (eval body context position last effective_axis env fncs)
+      Ast path_step [Astring tag,body]
+          |  memV path_step pathFunctions
+          -> foldr (\x r -> ((findV path_step pathFunctions) tag x)++r)
+                   [] (eval body context position last effective_axis env fncs)
+      Ast "step" (exp:predicates)
+          -> applyPredicates predicates (eval exp context position last effective_axis env fncs) True env fncs
+      Ast "predicate" [condition,body]
+          -> applyPredicates [condition] (eval body context position last effective_axis env fncs) True env fncs
+      Ast "append" args
+          -> appendText (map (\x -> eval x context position last effective_axis env fncs) args)
+      Ast "call" ((Avar fname):args)
+          -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of
+               [(_,len,f)] -> if (length args) == len
+                              then f (map (\x -> eval x context position last effective_axis env fncs) args)
+                              else error ("Wrong number of arguments in system call: "++fname)
+               _ -> case filter (\(n,_,_) -> n == fname) fncs of
+                      (_,params,body):_ -> if (length params) == (length args)
+                                           then eval body context undefv2 undefv3 ""
+                                                    ((zipWith (\p a -> (p,eval a context position last effective_axis env fncs))
+                                                              params args)++env) fncs
+                                           else error ("Wrong number of arguments in function call: "++fname)
+                      _ -> error ("Undefined function: "++fname)
+      Ast "construction" [Astring tag,Ast "attributes" [],body]
+          -> [ XElem tag [] 0 parent_error (eval body context position last effective_axis env fncs) ]
+      Ast "construction" [tag,Ast "attributes" al,body]
+             -> let alc = map (\(Ast "pair" [a,v])
+                                     -> let ac = eval a context position last effective_axis env fncs
+                                            vc = eval v context position last effective_axis env fncs
+                                        in (qName ac,showXS vc)) al
+                    ct = eval tag context position last effective_axis env fncs
+                    bc = eval body context position last effective_axis env fncs
+                in [ XElem (qName ct) alc 0 parent_error bc ]
+      Ast "let" [Avar var,source,body]
+          -> eval body context position last effective_axis
+                  ((var,eval source context position last effective_axis env fncs):env) fncs
+      Ast "for" [Avar var,Avar "$",source,body]      -- a for-loop without an index
+          -> foldr (\a r -> (eval body a undefv2 undefv3 "" ((var,[a]):env) fncs)++r)
+                   [] (eval source context position last effective_axis env fncs)
+      Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
+          -> let p = maxPosition (Avar ivar) body
+                 ns = if p > 0              -- there is a top-k like restriction
+                      then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
+                      else source 
+             in foldir (\a i r -> (eval body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs)++r)
+                       [] (eval ns context position last effective_axis env fncs) 1
+      Ast "sortTuple" (exp:orderBys)             -- prepare each FLWOR tuple for sorting
+          -> [ XElem "" [] 0 parent_error
+                     (foldl (\r a -> r++[XElem "" [] 0 parent_error (text (eval a context position last effective_axis env fncs))])
+                                     [XElem "" [] 0 parent_error (eval exp context position last effective_axis env fncs)] orderBys) ]
+      Ast "sort" (exp:ordList)                   -- blocking
+          -> let ce = map (\(XElem _ _ _ _ xs) -> map (\(XElem _ _ _ _ ys) -> ys) xs)
+                          (eval exp context position last effective_axis env fncs)
+                 ordering = foldr (\(Avar ord) r (x:xs) (y:ys)
+                                       -> case compareXSeqs (ord == "ascending") x y of
+                                            EQ -> r xs ys
+                                            o -> o)
+                                  (\xs ys -> EQ) ordList
+             in concatMap head (sortBy (\(_:xs) (_:ys) -> ordering xs ys) ce)
+      _ -> error ("Illegal XQuery: "++(show e))
+
+
+-- The monadic applyPredicates that propagates IO state
+applyPredicatesM :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> IO XSeq
+applyPredicatesM [] xs _ _ _ = return xs
+applyPredicatesM ((Aint n):preds) xs _ env fncs   -- shortcut that improves laziness
+    = applyPredicatesM preds [xs !! (n-1)] True env fncs
+applyPredicatesM (pred:preds) xs True env fncs    -- top-k like
+    | maxPosition pathPosition pred > 0
+    = applyPredicatesM (pred:preds) (take (maxPosition pathPosition pred) xs) False env fncs
+applyPredicatesM (pred:preds) xs _ env fncs
+    | containsLast pred         -- blocking: use only when last() is used in the predicate
+    = do let last = length xs
+         vs <- foldir (\x i r -> do vs <- evalM pred x i last "" env fncs
+                                    s <- r
+                                    return (if case vs of
+                                                 [XInt k] -> k == i               -- indexing
+                                                 b -> conditionTest b
+                                            then x:s else s))
+                      (return []) xs 1
+         applyPredicatesM preds vs True env fncs
+applyPredicatesM (pred:preds) xs _ env fncs
+    = do vs <- foldir (\x i r -> do vs <- evalM pred x i undefv3 "" env fncs
+                                    s <- r
+                                    return (if case vs of
+                                                 [XInt k] -> k == i               -- indexing
+                                                 b -> conditionTest b
+                                            then x:s else s))
+                      (return []) xs 1
+         applyPredicatesM preds vs True env fncs
+
+
+-- The monadic XQuery interpreter; it is like eval but has plumbing to propagate IO state
+evalM :: Ast -> XTree -> Int -> Int -> String -> Environment -> Functions -> IO XSeq
+evalM e context position last effective_axis env fncs
+  = case e of
+      Avar "." -> return [ context ]
+      Avar v -> return (findV v env)
+      Aint n -> return [ XInt n ]
+      Afloat n -> return [ XFloat n ]
+      Astring s -> return [ XText s ]
+      -- for non-IO XQuery, use the regular eval
+      Ast "nonIO" [u] -> return (eval u context position last effective_axis env fncs)
+      Ast "context" [v,Astring dp,body]
+          -> do vs <- evalM v context position last effective_axis env fncs
+                foldr (\x r -> (liftM2 (++)) (evalM body x position last dp env fncs) r)
+                      (return []) vs
+      Ast "call" [Avar "position"] -> return [XInt position]
+      Ast "call" [Avar "last"] -> return [XInt last]
+      Ast "child_step" [tag, Avar "."]
+          |  effective_axis /= ""
+          -> evalM (Ast effective_axis [tag, Avar "."]) context position last "" env fncs
+      Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
+          -> do vs <- evalM body context position last effective_axis env fncs
+                let ts = map (\(Avar tag) -> tag) tags
+                foldr (\x r -> (liftM2 (++)) (applyPredicatesM predicates (descendant_any_with_tagged_children ts x) True env fncs) r)
+                      (return []) vs
+      Ast "step" ((Ast path_step [Astring tag,body]):predicates)
+          |  memV path_step pathFunctions
+          -> do vs <- evalM body context position last effective_axis env fncs
+                foldr (\x r -> (liftM2 (++)) (applyPredicatesM predicates ((findV path_step pathFunctions) tag x) True env fncs) r)
+                      (return []) vs
+      Ast "descendant_any" (body:tags)
+          -> do vs <- evalM body context position last effective_axis env fncs
+                let ts = map (\(Avar tag) -> tag) tags
+                return (foldr (\x r -> (descendant_any_with_tagged_children ts x)++r) [] vs)
+      Ast path_step [Astring tag,body]
+          |  memV path_step pathFunctions
+          -> do vs <- evalM body context position last effective_axis env fncs
+                return (foldr (\x r -> ((findV path_step pathFunctions) tag x)++r) [] vs)
+      Ast "step" (exp:predicates)
+          -> do vs <- evalM exp context position last effective_axis env fncs
+                applyPredicatesM predicates vs True env fncs
+      Ast "predicate" [condition,body]
+          -> do vs <- evalM body context position last effective_axis env fncs
+                applyPredicatesM [condition] vs True env fncs
+      Ast "executeSQL" [Avar var,args]
+          -> do as <- evalM args context position last effective_axis env fncs
+                let [XStmt stmt] = findV var env
+                executeSQL stmt as
+      Ast "call" [Avar nm,c,t,e]     -- this is the only lazy function
+          | elem nm ["if","fn:if"]
+          -> do ce <- evalM c context position last effective_axis env fncs
+                evalM (if conditionTest ce then t else e) context position last effective_axis env fncs
+      Ast "append" args
+          -> (liftM appendText) (mapM (\x -> evalM x context position last effective_axis env fncs) args)
+      Ast "call" ((Avar fname):args)        -- Note: strict function application
+          -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of
+               [(_,len,f)] -> if (length args) == len
+                              then (liftM f) (mapM (\x -> evalM x context position last effective_axis env fncs) args)
+                              else error ("Wrong number of arguments in system call: "++fname)
+               _ -> case filter (\(n,_,_) -> n == fname) fncs of
+                      (_,params,body):_ -> if (length params) == (length args)
+                                           then do vs <- mapM (\a -> evalM a context position last effective_axis env fncs) args
+                                                   evalM body context undefv2 undefv3 ""
+                                                             ((zipWith (\p a -> (p,a)) params vs)++env) fncs
+                                           else error ("Wrong number of arguments in function call: "++fname)
+                      _ -> error ("Undefined function: "++fname)
+      Ast "construction" [Astring tag,Ast "attributes" [],body]
+          -> do b <- evalM body context position last effective_axis env fncs
+                return [ XElem tag [] 0 parent_error b ]
+      Ast "construction" [tag,Ast "attributes" al,body]
+             -> do alc <- mapM (\(Ast "pair" [a,v])
+                                     -> do ac <- evalM a context position last effective_axis env fncs
+                                           vc <- evalM v context position last effective_axis env fncs
+                                           return (qName ac,showXS vc)) al
+                   ct <- evalM tag context position last effective_axis env fncs
+                   bc <- evalM body context position last effective_axis env fncs
+                   return [ XElem (qName ct) alc 0 parent_error bc ]
+      Ast "let" [Avar var,source,body]
+          -> do s <- evalM source context position last effective_axis env fncs
+                evalM body context position last effective_axis ((var,s):env) fncs
+      Ast "for" [Avar var,Avar "$",source,body]      -- a for-loop without an index
+          -> do vs <- evalM source context position last effective_axis env fncs
+                foldr (\a r -> (liftM2 (++)) (evalM body a undefv2 undefv3 "" ((var,[a]):env) fncs) r)
+                      (return []) vs
+      Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
+          -> do let p = maxPosition (Avar ivar) body
+                    ns = if p > 0              -- there is a top-k like restriction
+                            then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
+                            else source 
+                vs <- evalM ns context position last effective_axis env fncs
+                foldir (\a i r -> (liftM2 (++)) (evalM body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs) r)
+                       (return []) vs 1
+      Ast "sortTuple" (exp:orderBys)             -- prepare each FLWOR tuple for sorting
+          -> do vs <- evalM exp context position last effective_axis env fncs
+                os <- mapM (\a -> evalM a context position last effective_axis env fncs) orderBys
+                return [ XElem "" [] 0 parent_error (foldl (\r a -> r++[XElem "" [] 0 parent_error (text a)])
+                                                               [XElem "" [] 0 parent_error vs] os) ]
+      Ast "sort" (exp:ordList)                   -- blocking
+          -> do vs <- evalM exp context position last effective_axis env fncs
+                let ce = map (\(XElem _ _ _ _ xs) -> map (\(XElem _ _ _ _ ys) -> ys) xs) vs
+                    ordering = foldr (\(Avar ord) r (x:xs) (y:ys)
+                                       -> case compareXSeqs (ord == "ascending") x y of
+                                            EQ -> r xs ys
+                                            o -> o)
+                                  (\xs ys -> EQ) ordList
+                return (concatMap head (sortBy (\(_:xs) (_:ys) -> ordering xs ys) ce))
+      _ -> error ("Illegal XQuery: "++(show e))
+
+
+-- evaluate from input continuously
+evalInput :: (String -> Environment -> Functions -> IO(Environment,Functions)) -> Environment -> Functions -> IO ()
+evalInput eval vs fs
+    = do let oneline prompt = do line <- readline prompt
+                                 case line of
+                                   Nothing -> return "quit"
+                                   Just t -> if t == ""
+                                             then oneline prompt
+                                             else return t
+             readlines x = do line <- oneline ": "
+                              if last line == '}'
+                                 then return (x++" "++(init line))
+                                 else if line == "quit"
+                                      then return line
+                                      else readlines (x++" "++line)
+         line <- oneline "> "
+         stmt <- if head line == '{'
+                 then if last line == '}'
+                      then return (init (tail line))
+                      else readlines (tail line)
+                 else return line
+         if stmt == "quit"
+            then putStrLn "Bye!"
+            else do addHistory stmt
+                    (nvs,nfs) <- eval (map (\c -> if c=='\"' then '\'' else c) stmt) vs fs
+                    evalInput eval nvs nfs
+
+
+xqueryE :: String -> Environment -> Functions -> (String -> IO XSeq) -> Bool -> IO (XSeq,Environment,Functions)
+xqueryE query variables functions dbmapper verbose
+    = do let asts = parse (scan query)
+             fncs = foldr (\e r -> case e of
+                                     Ast "function" ((Avar f):b:args) -> (f,map (\(Avar v) -> v) args,optimize b):r
+                                     _ -> r) functions asts
+         vars <- foldl (\r e -> case e of
+                                  Ast "variable" [Avar v,u]
+                                      -> do s <- r
+                                            uv <- evalM (optimize u) undefv1 undefv2 undefv3 "" s fncs
+                                            return ((v,uv):s)
+                                  _ -> r) (return variables) asts
+         let exprp e = case e of Ast f _ | elem f ["function","variable"] -> True; _ -> False
+             exps = concatenateAll (dropWhile exprp asts)
+             opt_exps = optimize exps
+             (ast,ns) = liftIOSources opt_exps
+         if verbose
+            then do putStrLn "Abstract Syntax Tree (AST):"
+                    putStrLn (ppAst exps)
+                    putStrLn "Optimized AST:"
+                    putStrLn (ppAst opt_exps)
+                    putStrLn "Result:"
+            else return ()
+         env <- foldr (\(n,s) r -> case s of
+                                     Avar m -> do env <- r
+                                                  return ((n,findV m env):env)
+                                     Ast "prepareSQL" [Astring sql]
+                                         -> do env <- r
+                                               t <- dbmapper sql
+                                               return ((n,t):env)
+                                     Astring file -> do doc <- readFile file
+                                                        env <- r
+                                                        return ((n,[materialize (parseDocument doc)]):env))
+                      (return []) ns
+         e <- evalM ast undefv1 undefv2 undefv3 "" (env++vars) fncs
+         return (e,vars,fncs)
+
+
+-- | Evaluate the XQuery using the interpreter.
+xquery :: String -> IO XSeq
+xquery query = do (u,_,_) <- xqueryE query [] [] (\sql -> return []) False
+                  return u
+
+
+-- | Read an XQuery from a file and run it using the interpreter.
+xfile :: String -> IO XSeq
+xfile file = do query <- readFile file
+                xquery query
+
+
+-- | Evaluate the XQuery with database connectivity using the interpreter.
+xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq
+xqueryDB query db = do (u,_,_) <- xqueryE query [] []
+                                  (\sql -> do stmt <- prepareSQL db sql
+                                              return [XStmt stmt]) False
+                       return u
+
+
+-- | Read an XQuery with database connectivity from a file and run it using the interpreter.
+xfileDB :: (IConnection conn) => String -> conn -> IO XSeq
+xfileDB file db = do query <- readFile file
+                     xqueryDB query db
diff --git a/Text/XML/HXQ/Optimizer.hs b/Text/XML/HXQ/Optimizer.hs
new file mode 100644
--- /dev/null
+++ b/Text/XML/HXQ/Optimizer.hs
@@ -0,0 +1,517 @@
+{-------------------------------------------------------------------------------------
+-
+- Preprocess abstract syntax trees, remove backward steps and optimize
+- Programmer: Leonidas Fegaras
+- Email: fegaras@cse.uta.edu
+- Web: http://lambda.uta.edu/
+- Creation: 05/01/08, last update: 07/24/08
+- 
+- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
+- This material is provided as is, with absolutely no warranty expressed or implied.
+- Any use is at your own risk. Permission is hereby granted to use or copy this program
+- for any purpose, provided the above notices are retained on all copies.
+-
+--------------------------------------------------------------------------------------}
+
+
+module Text.XML.HXQ.Optimizer(optimize) where
+
+import Control.Monad
+import Char(toLower)
+import HXML(AttList)
+import Text.XML.HXQ.Parser
+import Text.XML.HXQ.XTree
+import Text.XML.HXQ.DB
+
+
+
+paths = [ "current_step", "child_step", "descendant_step", "attribute_step", "attribute_descendant_step" ]
+
+
+distinct :: Eq a => [a] -> [a]
+distinct = foldl (\r a -> if elem a r then r else r++[a]) []
+
+
+-- collect attribute constructions inside element constructions
+collect_attributes :: Ast -> (Ast,[Ast])
+collect_attributes (Ast "attribute_construction" [attr,value])
+    = (Ast "call" [Avar "empty"],[Ast "pair" [attr,value]])
+collect_attributes (Ast "call" [Avar "concatenate",x,y])
+    = let (cx,ax) = collect_attributes x
+          (cy,ay) = collect_attributes y
+      in (Ast "call" [Avar "concatenate",cx,cy],ax++ay)
+collect_attributes (Ast "append" es)
+    = let (s,a) = foldr (\e (r,ar) -> let (cx,ax) = collect_attributes e in (cx:r,ax++ar)) ([],[]) es
+      in (Ast "append" s,a)
+collect_attributes (Ast "step" (e:es))
+    = let (ce,ae) = collect_attributes e
+      in (Ast "step" (ce:es),ae)
+collect_attributes e = (e,[])
+
+
+-- does the expression contain a $var/.. ?
+parentOfVar :: Ast -> String -> Bool
+parentOfVar (Ast "step" [Ast "parent_step" [Ast "step" [Avar x]]]) var = x == var
+parentOfVar (Ast "let" [Avar v,s,_]) var | var == v = parentOfVar s var
+parentOfVar (Ast "for" [Avar v,Avar i,s,_]) var | var == v || var == i = parentOfVar s var
+parentOfVar (Ast _ args) var = or (map (\x -> parentOfVar x var) args)
+parentOfVar _ _ = False
+
+
+-- replace $var/.. with $nvar
+replaceParentOfVar :: Ast -> String -> String -> Ast
+replaceParentOfVar (Ast "step" [Ast "parent_step" [Ast "step" [Avar x]]]) var nvar
+    | x == var
+    = Avar nvar
+replaceParentOfVar (Ast "let" [Avar v,s,b]) var nvar | var == v
+    = Ast "let" [Avar v,replaceParentOfVar s var nvar,b]
+replaceParentOfVar (Ast "for" [Avar v,Avar i,s,b]) var nvar | var == v || var == i
+    = Ast "for" [Avar v,Avar i,replaceParentOfVar s var nvar,b]
+replaceParentOfVar (Ast f args) var nvar
+    = Ast f (map (\x -> replaceParentOfVar x var nvar) args)
+replaceParentOfVar e _ _ = e
+
+
+-- Rules to extract the parent of an XQuery expression
+-- For every XQuery x and predicates p1 ... pn and for s in [tag,*,@attr]:
+--    x/s[p1]...[pn]/..   ->  x[s[p1]...[pn]]
+--    x//s[p1]...[pn]/..  ->  x//*[s[p1]...[pn]]
+removeParent :: Ast -> (Ast,Ast,Bool,Ast)
+removeParent (Ast "predicate" [c,x])
+         = let (nx,cond,childp,tag) = removeParent x
+           in (Ast "predicate" [c,nx],cond,childp,tag)
+removeParent (Ast "step" ((Ast "child_step" [tag,x]):preds))
+    = (Ast "step" ((Ast "child_step" [tag,Avar "."]):preds),x,True,tag)
+removeParent (Ast "step" ((Ast "descendant_step" [tag,x]):preds))
+    = (Ast "step" ((Ast "child_step" [tag,Avar "."]):preds),
+       Ast "step" [Ast "descendant_step" [Astring "*",x]],True,tag)
+removeParent (Ast "step" ((Ast "attribute_step" [tag,x]):preds))
+    = (Ast "step" ((Ast "attribute_step" [tag,Avar "."]):preds),x,False,tag)
+removeParent (Ast "step" ((Ast "descendant_attribute_step" [tag,x]):preds))
+    = (Ast "step" ((Ast "attribute_step" [tag,Avar "."]):preds),
+       Ast "step" ((Ast "descendant_step" [Astring "*",x]):preds),False,tag)
+removeParent (Ast "step" (x:xs))
+         = let (nx,cond,childp,tag) = removeParent x
+           in (Ast "step" (nx:xs),cond,childp,tag)
+removeParent e = error ("Cannot remove this parent step "++(show e))
+
+
+tagged_children :: String -> Ast -> [Tag]
+tagged_children context (Ast "step" ((Ast "child_step" [Astring tag,Avar "."]):_))
+    | context == "."
+    = [tag]
+tagged_children context (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Avar v):_)]):_))
+    | v == context
+    = [tag]
+tagged_children _ (Ast "step" ((Ast "descendant_any" _):_)) = []
+tagged_children _ (Ast "step" ((Ast step _):_))
+    | elem step paths = []
+tagged_children context (Ast _ xs) = concatMap (tagged_children context) xs
+tagged_children _ _ = []
+
+
+empty = Ast "call" [Avar "empty"]
+
+
+simplify :: Ast -> Ast
+-- must be done bottom-up:    /../..
+simplify (Ast "step" [Ast "parent_step" [Ast "step" [Ast "parent_step" x]]])
+    = let nx = simplify (Ast "step" [Ast "parent_step" x])
+      in simplify (Ast "step" [Ast "parent_step" [nx]])
+-- get rid of a parent step
+simplify (Ast "step" [Ast "parent_step" [x]])
+    = let (cond,nx,_,_) = removeParent x
+      in Ast "predicate" [simplify cond,simplify nx]
+-- remove $var/.. in a let-FLWOR
+simplify (Ast "let" [Avar var,source,body])
+    | parentOfVar body var
+    = let (cond,nx,childp,tag) = removeParent source
+      in simplify (Ast "let" [Avar (var++"_parent"),Ast "predicate" [cond,nx],
+                              Ast "let" [Avar var,
+                                         Ast "step" [ Ast (if childp
+                                                           then "child_step"
+                                                           else "attribute_step")
+                                                      [tag,Avar (var++"_parent")] ],
+                                         replaceParentOfVar body var (var++"_parent")]])
+-- remove $var/.. from a for-FLWOR
+simplify (Ast "for" [Avar var,Avar "$",source,body])
+    | parentOfVar body var
+    = let (cond,nx,childp,tag) = removeParent source
+      in simplify (Ast "for" [Avar (var++"_parent"),Avar "$",Ast "predicate" [cond,nx],
+                              Ast "for" [Avar var,Avar "$",
+                                         Ast "step" [ Ast (if childp
+                                                           then "child_step"
+                                                           else "attribute_step")
+                                                      [tag,Avar (var++"_parent")] ],
+                                         replaceParentOfVar body var (var++"_parent")]])
+-- pull out attributes from a general element construction
+simplify (Ast "element_construction" [tag,Ast "attributes" as,content])
+    = let (nc,attrs) = collect_attributes content
+      in simplify (Ast "construction" [tag,Ast "attributes" (as++attrs),nc])
+-- if //* collect all children tagnames to use descendant_any_with_tagged_children
+simplify (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)],body])
+    | not (null ((tagged_children var body))) || any (not . null . (tagged_children ".")) preds
+    = let ctags = distinct ((tagged_children var body)++(concatMap (tagged_children ".") preds))
+          tags = map Avar ctags
+      in simplify (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_any" (path:tags)):preds)],body])
+simplify (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)]):preds2))
+    = let ctags = distinct(tag:(concatMap (tagged_children ".") preds))
+          tags = map Avar ctags
+      in simplify (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_any" (path:tags)):preds)]):preds2))
+simplify (Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds))
+    | any (not . null . (tagged_children ".")) preds
+    = let ctags = distinct (concatMap (tagged_children ".") preds)
+          tags = map Avar ctags
+      in simplify (Ast "step" ((Ast "descendant_any" (path:tags)):preds))
+-- expand the wrapper of a stored document
+simplify (Ast "call" [Avar "publish",Astring dbpath,Astring name])
+    = simplify (publishXmlDoc dbpath name)
+-- default
+simplify (Ast n args) = Ast n (map simplify args)
+simplify e = e
+
+
+taggedElement :: [Ast] -> String -> Maybe [Ast]
+taggedElement (e@(Ast "construction" [Astring ctag,_,x]):xs) tag
+    | ctag == tag || tag == "*"
+    = case taggedElement xs tag of
+        Nothing -> Nothing
+        Just s -> Just (e:s)
+taggedElement ((Ast "construction" [_,_,_]):xs) tag
+    = taggedElement xs tag
+taggedElement ((Ast "call" [Avar "concatenate",x,y]):xs) tag
+    = case (taggedElement (x:xs) tag,taggedElement (y:xs) tag) of
+        (Just tx,Just ty) -> Just (tx++ty)
+        _ -> Nothing
+taggedElement ((Astring _):xs) tag
+    = taggedElement xs tag
+taggedElement ((Aint _):xs) tag
+    = taggedElement xs tag
+taggedElement (e:xs) tag = Nothing
+taggedElement [] _ = Just []
+
+
+findAttr :: String -> [Ast] -> Ast
+findAttr tag ((Ast "pair" [Astring a,v]):_) | a==tag || tag=="*" = v
+findAttr tag (_:xs) = findAttr tag xs
+findAttr _ [] = empty
+
+
+andAll :: [Ast] -> Ast
+andAll [x] = x
+andAll (x:xs) = foldl (\a r -> call "and" [a,r]) x xs
+
+
+occursContext :: Ast -> Int
+occursContext e
+    = case e of
+        Avar "." -> 1
+        Ast "let" _ -> 0
+        Ast "for" _ -> 0
+        Ast "call" [Avar "SQL",s,f,w]
+            -> occursContext w
+        Ast "descendant_any" (x:tags)
+            -> occursContext x
+        Ast step [tag,x]
+            | elem step paths
+            -> occursContext x
+        Ast n xs -> sum (map occursContext xs)
+        _ -> 0
+
+
+substContext :: Ast -> Ast -> Ast
+substContext e b
+    = case b of
+        Avar "." -> e
+        Ast "let" _ -> b
+        Ast "for" _ -> b
+        Ast "call" [Avar "SQL",s,f,w]
+            -> Ast "call" [Avar "SQL",s,f,substContext e w]
+        Ast "descendant_any" (x:tags)
+            -> Ast "descendant_any" ((substContext e x):tags)
+        Ast step [tag,x]
+            | elem step paths
+            -> Ast step [tag,substContext e x]
+        Ast n xs -> Ast n (map (substContext e) xs)
+        _ -> b
+
+
+occurs :: String -> Ast -> Int
+occurs v e
+    = case e of
+        Avar w | v==w -> 1
+        Ast "let" [Avar w,_,_] | v==w -> 0
+        Ast "for" [Avar w,Avar i,_,_] | v==w || v==i -> 0
+        Ast "call" [Avar "SQL",s,f,w]
+            -> occurs v w
+        Ast n xs -> sum (map (occurs v) xs)
+        _ -> 0
+
+
+subst :: String -> Ast -> Ast -> Ast
+subst v e b
+    = case b of
+        Avar w | v==w -> e
+        Ast "let" [Avar w,_,_] | v==w -> b
+        Ast "for" [Avar w,Avar i,_,_] | v==w || v==i -> b
+        Ast "call" [Avar "SQL",s,f,w]
+            -> Ast "call" [Avar "SQL",s,f,subst v e w]
+        Ast n xs -> Ast n (map (subst v e) xs)
+        _ -> b
+
+
+dependsOnPosition :: Bool -> Ast -> Bool
+dependsOnPosition contextp e
+    = case e of
+        Avar "." -> contextp
+        Ast "call" [Avar "position"] -> True
+        Ast "call" [Avar "last"] -> True
+        Ast "call" ((Avar "step"):x:_)
+            -> dependsOnPosition contextp x
+        Ast _ xs -> any (dependsOnPosition contextp) xs
+        _ -> False
+
+
+wellFormedPredicate :: Bool -> Ast -> Bool
+wellFormedPredicate contextp e
+    = case e of
+        Ast "call" ((Avar "step"):x:_)
+            -> not (dependsOnPosition contextp x)
+        Ast step xs
+            | elem step paths || step == "descendant_any"
+            -> not (any (dependsOnPosition contextp) xs)
+        Ast "construction" xs
+            -> not (any (dependsOnPosition contextp) xs)
+        Ast "call" [Avar "not",x]
+            -> not (dependsOnPosition contextp x)
+        Ast "call" [Avar cmp,x,y]
+            | any (\(f,_) -> f==cmp) (sqlComparisson++sqlBoolean)
+            -> not (dependsOnPosition contextp x)
+               && not (dependsOnPosition contextp y)
+        _ -> False
+
+
+splitSqlPredicate :: [String] -> Ast -> Maybe(Ast,Ast)
+splitSqlPredicate tables (Ast "call" [Avar "and",p1,p2])
+    = case (splitSqlPredicate tables p1,splitSqlPredicate tables p2) of
+        (Nothing,Nothing) -> Nothing
+        (Nothing,Just(pp1,pp2)) -> Just(pp1,Ast "call" [Avar "and",p1,pp2])
+        (Just(pp1,pp2),Nothing) -> Just(pp1,Ast "call" [Avar "and",p2,pp2])
+splitSqlPredicate tables pred
+    | sqlPredicate tables pred
+    = Just(pred,Ast "call" [Avar "true"])
+splitSqlPredicate tables pred = Nothing
+
+
+-- Normalization
+normalize :: Ast -> Bool -> Int -> (Ast,Bool,Int)
+normalize exp changed count
+    = case exp of
+        Ast "step" [x]
+            -> normalize x True count
+        Ast "step" (x:(Ast "call" [Avar "true"]):xs)
+            -> norm (Ast "step" (x:xs))
+        Ast "step" (x:(Ast "call" [Avar "false"]):xs)
+            -> (empty,True,count)
+        Ast "for" [v,i,Ast "call" [Avar "empty"],b]
+            -> (empty,True,count)
+        Ast "for" [v,i,s,Ast "call" [Avar "empty"]]
+            -> (empty,True,count)
+        Ast "descendant_any" ((Astring _):_)
+            -> (empty,True,count)
+        Ast "descendant_any" ((Aint _):_)
+            -> (empty,True,count)
+        Ast "descendant_any" ((Afloat _):_)
+            -> (empty,True,count)
+        Ast "descendant_any" ((Ast "call" [Avar "text",_]):_)
+            -> (empty,True,count)
+        Ast "descendant_any" ((Ast "call" [Avar "empty"]):_)
+            -> (empty,True,count)
+        Ast step [_,Astring _]
+            | elem step paths
+            -> (empty,True,count)
+        Ast step [_,Aint _]
+            | elem step paths
+            -> (empty,True,count)
+        Ast step [_,Afloat _]
+            | elem step paths
+            -> (empty,True,count)
+        Ast step [_,Ast "call" [Avar "text",_]]
+            | elem step paths
+            -> (empty,True,count)
+        Ast step [_,Ast "call" [Avar "empty"]]
+            | elem step paths
+            -> (empty,True,count)
+        Ast "call" [Avar "and",Ast "call" [Avar "true"],x]
+            -> norm x
+        Ast "call" [Avar "and",x,Ast "call" [Avar "true"]]
+            -> norm x
+        -- (x,())  ->  x
+        Ast "call" [Avar "concatenate",x,Ast "call" [Avar "empty"]]
+            -> norm x
+        -- ((),x)  ->  x
+        Ast "call" [Avar "concatenate",Ast "call" [Avar "empty"],x]
+            -> norm x
+        -- for $v1 in (for $v2 in s2 return b2) return b1  -->  for $v2 in s2, for $v1 in b2 return b1
+        Ast "for" [v1,i1,Ast "for" [v2,i2,s2,b2],b1]
+            -> norm (Ast "for" [v2,i2,s2,Ast "for" [v1,i1,b2,b1]])
+        -- (for $v in s return b)/tag  -->  for $v in s return b/tag  -->  
+        Ast "descendant_any" ((Ast "for" [v,i,s,b]):tags)
+            -> norm (Ast "for" [v,i,s,Ast "descendant_any" (b:tags)])
+        Ast step [tag,Ast "for" [v,i,s,b]]
+            | elem step paths
+            -> norm (Ast "for" [v,i,s,Ast step [tag,b]])
+        -- (x,y)/tag  -->  (x/tag,y/tag)
+        Ast "descendant_any" ((Ast "call" [Avar "concatenate",x,y]):tags)
+            -> norm (Ast "call" [Avar "concatenate",Ast "descendant_any" (x:tags),Ast "descendant_any" (y:tags)])
+        Ast step [tag,Ast "call" [Avar "concatenate",x,y]]
+            | elem step paths
+            -> norm (Ast "call" [Avar "concatenate",Ast step [tag,x],Ast step [tag,y]])
+        -- for $v in (x,y) return b  -->  (for $v in x return b,for $v in y return b)
+        Ast "for" [v,i@(Avar "$"),Ast "call" [Avar "concatenate",x,y],b]
+            -> norm (Ast "call" [Avar "concatenate",Ast "for" [v,i,x,b],Ast "for" [v,i,y,b]])
+        -- for $v in <a>...</a> return b  -->  b[$v/(<a>...</a>)]
+        Ast "for" [Avar v,Avar i,e,b]
+            | case e of Ast "construction" _ -> True; Ast _ _ -> False; _ -> True
+            -> norm (if i == "$"
+                     then subst v e b
+                     else subst v e (subst i (Aint 1) b))
+        --Ast "for" [Avar v,Avar i,Ast "predicate" [pred,e],b]
+        --    -> norm (Ast "for" [Avar v,Avar i,e,Ast "predicate" [pred,b]])
+        Ast "for" [Avar v,Avar i,Ast "predicate" [pred,e],b]
+            | occurs v pred == 0 && occurs i pred == 0 && occursContext pred == 0
+            -> norm (Ast "predicate" [pred,Ast "for" [Avar v,Avar i,e,b]])
+        -- unfold linear let
+        Ast "let" [Avar v,e,b]
+            | occurs v b < 2
+            -> norm (subst v e b)
+        -- (if c then t else e)/A  -->  if c then t/A else e/A
+        Ast "descendant_any" ((Ast "predicate" [c,e]):tags)
+            | wellFormedPredicate True c
+            -> norm (Ast "predicate" [c,Ast "descendant_any" (e:tags)])
+        Ast step [tag,Ast "predicate" [c,e]]
+            | elem step paths && wellFormedPredicate True c
+            -> norm (Ast "predicate" [c,Ast step [tag,e]])
+        -- if p doesn't depend on context:  (e[p])/A  -->  (e/A)[p]
+        Ast "descendant_any" ((Ast "step" (x:xs@(_:_))):tags)
+            | all (wellFormedPredicate True) xs
+            -> norm (Ast "step" ((Ast "descendant_any" (x:tags)):xs))
+        Ast step [tag,Ast "step" (x:xs@(_:_))]
+            | elem step paths && all (wellFormedPredicate True) xs
+            -> norm (Ast "step" ((Ast step [tag,x]):xs))
+        -- normalize predicate
+        Ast "predicate" [pred,x]
+            | occursContext pred > 0
+            -> let v = "x"++show count
+               in normalize (Ast "for" [Avar v,Avar "$",x,Ast "predicate" [substContext (Avar v) pred,Avar v]]) True (count+1)
+        Ast "step" [x,pred]
+            | occursContext pred > 0
+            -> let v = "x"++show count
+               in normalize (Ast "for" [Avar v,Avar "$",x,Ast "predicate" [substContext (Avar v) pred,Avar v]]) True (count+1)
+        Ast "predicate" [p1,Ast "predicate" [p2,e]]
+            -> norm (Ast "predicate" [Ast "call" [Avar "and",p1,p2],e])
+        Ast "predicate" [Ast "call"[Avar "false"],x]
+            -> (empty,True,count)
+        Ast "predicate" [Ast "call"[Avar "true"],x]
+            -> (x,True,count)
+        Ast "predicate" [x,Ast "call"[Avar "empty"]]
+            -> (empty,True,count)
+        Ast "step" ((Ast "call" [Avar "empty"]):xs)
+            -> (empty,True,count)
+        -- promote well-formed predicates; but note:  (x,y)[1] <> (x[1],y[1])
+        Ast "step" ((Ast "call" [Avar "concatenate",x,y]):xs)
+            | all (wellFormedPredicate False) xs
+            -> norm (Ast "call" [Avar "concatenate",Ast "step" (x:xs),Ast "step" (y:xs)])
+        Ast "predicate" [pred,Ast "for" [v,i,s,b]]
+            | wellFormedPredicate False pred
+            -> norm (Ast "for" [v,i,s,Ast "predicate" [pred,b]])
+        Ast "step" ((Ast "for" [v,i,s,b]):xs)
+            | all (wellFormedPredicate False) xs
+            -> norm (Ast "for" [v,i,s,Ast "predicate" [andAll xs,b]])
+        Ast "step" (e@(Ast "construction" [_,_,_]):xs)
+            -> if sum (map occursContext xs) > 0
+               then norm (Ast "predicate" [andAll (map (substContext e) xs),e])
+               else let (r,b,c) = foldr (\a (r,b,c) -> let (x,s,i) = normalize a b c in (x:r,s,i))
+                                        ([],changed,count) (e:xs)
+                    in (Ast "step" r,b,c)
+        Ast "call" [Avar "=",x,y]
+            | x == empty || y == empty
+            -> (Ast "call"[Avar "true"],True,count)
+        -- (<ctag>...<tag>...</tag>...</ctag>)/tag  -->  ...<tag>...</tag>...
+        Ast "child_step" [Astring tag,Ast "construction" [_,_,Ast "append" x]]
+            | taggedElement x tag /= Nothing
+            -> case taggedElement x tag of
+                 Just [] -> (empty,True,count)
+                 Just s -> norm (concatenateAll s)
+        Ast "child_step" [Astring tag,Ast "construction" [_,_,Ast "append" x]]
+            -> norm (Ast "current_step" [Astring tag,concatenateAll x])
+        Ast "current_step" [Astring tag1,e@(Ast "construction" [Astring tag2,_,Ast "append" x])]
+            -> if tag1 == tag2 || tag1 == "*"
+               then norm e
+               else (empty,True,count)
+        -- (<tag>x</tag>)//tag  --> (x,x//tag)
+        Ast "descendant_any" (z@(Ast "construction" [Astring ctag,_,Ast "append" x]):tags)
+            -> norm (Ast "call" [Avar "concatenate",z,Ast "descendant_any" ((concatenateAll x):tags)])
+        Ast "descendant_step" [Astring tag,z@(Ast "construction" [Astring ctag,_,Ast "append" x])]
+            -> norm (if tag == ctag || tag == "*"
+                     then Ast "call" [Avar "concatenate",z,Ast "descendant_step" [Astring tag,concatenateAll x]]
+                     else Ast "descendant_step" [Astring tag,concatenateAll x])
+        -- (<tag A=s>x</tag>)/@A  --> s
+        Ast "attribute_step" [Astring tag,Ast "construction" [ctag,Ast "attributes" as,x]]
+            -> (findAttr tag as,True,count)
+        -- (<tag A=s>x</tag>)//@A  --> (s,x//@A)
+        Ast "attribute_descendant_step" [Astring tag,Ast "construction" [ctag,Ast "attributes" as,Ast "append" x]]
+            -> norm (Ast "call" [Avar "concatenate",findAttr tag as,
+                                 Ast "attribute_descendant_step" [Astring tag,concatenateAll x]])
+        -- SQL folding
+        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],
+                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],b]]
+            | occurs v1 b == 0
+            -> norm (Ast "for" [Avar v2,Avar "$",
+                                Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):(s1++s2)),
+                                            Ast "call" ((Avar "from"):(f1++f2)),Ast "call" [Avar "and",pred1,pred2]],
+                                b])
+        Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "from"):tables),pred1],
+                   Ast "predicate" [pred2,x]]
+            | splitSqlPredicate [ v | Avar v <- tables ] pred2 /= Nothing
+            -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- tables ] pred2
+               in norm (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),
+                                                               Ast "call" ((Avar "from"):tables),Ast "call" [Avar "and",pred1,pred3]],
+                                   Ast "predicate" [pred4,x]])
+        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],
+                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],
+                              Ast "predicate" [predd,b]]]
+            | occurs v1 b == 0 && splitSqlPredicate [ v | Avar v <- f1 ] predd /= Nothing
+            -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- f1 ] predd
+               in norm (Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),
+                                                                Ast "call" ((Avar "from"):f1),Ast "call" [Avar "and",pred1,pred3]],
+                                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],
+                                              Ast "predicate" [pred4,b]]])
+        -- default
+        Ast n args
+            -> let (r,b,c) = foldr (\a (r,b,c) -> let (x,s,i) = normalize a b c in (x:r,s,i))
+                                   ([],changed,count) args
+               in (Ast n r,b,c)
+        _ -> (exp,changed,count)
+    where norm e = normalize e True count
+
+
+foldSQL :: Ast -> Ast
+foldSQL e
+    = case e of
+        Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):cols),Ast "call" ((Avar "from"):tables),pred]
+            -> let (sql,args) = makeSQL tables pred cols
+               in Ast "call" [Avar "sql",Astring sql,concatenateAll args]
+        Ast n args -> Ast n (map foldSQL args)
+        _ -> e
+
+
+optimizeLoop :: Ast -> Int -> (Ast,Int)
+optimizeLoop e c = let (ne,b,c') = normalize e False c
+                   in if b
+                      then optimizeLoop ne c'
+                      else (ne,c)
+
+
+optimize :: Ast -> Ast
+optimize e = foldSQL (fst (optimizeLoop (simplify e) 0))
diff --git a/Text/XML/HXQ/Parser.hs b/Text/XML/HXQ/Parser.hs
new file mode 100644
--- /dev/null
+++ b/Text/XML/HXQ/Parser.hs
@@ -0,0 +1,2153 @@
+{-# OPTIONS -fglasgow-exts -cpp #-}
+module Text.XML.HXQ.Parser where
+import Char
+#if __GLASGOW_HASKELL__ >= 503
+import Data.Array
+#else
+import Array
+#endif
+#if __GLASGOW_HASKELL__ >= 503
+import GHC.Exts
+#else
+import GlaExts
+#endif
+
+-- parser produced by Happy Version 1.17
+
+newtype HappyAbsSyn  = HappyAbsSyn HappyAny
+#if __GLASGOW_HASKELL__ >= 607
+type HappyAny = GHC.Exts.Any
+#else
+type HappyAny = forall a . a
+#endif
+happyIn4 :: ([ Ast ]) -> (HappyAbsSyn )
+happyIn4 x = unsafeCoerce# x
+{-# INLINE happyIn4 #-}
+happyOut4 :: (HappyAbsSyn ) -> ([ Ast ])
+happyOut4 x = unsafeCoerce# x
+{-# INLINE happyOut4 #-}
+happyIn5 :: (Ast) -> (HappyAbsSyn )
+happyIn5 x = unsafeCoerce# x
+{-# INLINE happyIn5 #-}
+happyOut5 :: (HappyAbsSyn ) -> (Ast)
+happyOut5 x = unsafeCoerce# x
+{-# INLINE happyOut5 #-}
+happyIn6 :: ([ Ast ]) -> (HappyAbsSyn )
+happyIn6 x = unsafeCoerce# x
+{-# INLINE happyIn6 #-}
+happyOut6 :: (HappyAbsSyn ) -> ([ Ast ])
+happyOut6 x = unsafeCoerce# x
+{-# INLINE happyOut6 #-}
+happyIn7 :: (Ast) -> (HappyAbsSyn )
+happyIn7 x = unsafeCoerce# x
+{-# INLINE happyIn7 #-}
+happyOut7 :: (HappyAbsSyn ) -> (Ast)
+happyOut7 x = unsafeCoerce# x
+{-# INLINE happyOut7 #-}
+happyIn8 :: (Ast) -> (HappyAbsSyn )
+happyIn8 x = unsafeCoerce# x
+{-# INLINE happyIn8 #-}
+happyOut8 :: (HappyAbsSyn ) -> (Ast)
+happyOut8 x = unsafeCoerce# x
+{-# INLINE happyOut8 #-}
+happyIn9 :: ([ Ast ]) -> (HappyAbsSyn )
+happyIn9 x = unsafeCoerce# x
+{-# INLINE happyIn9 #-}
+happyOut9 :: (HappyAbsSyn ) -> ([ Ast ])
+happyOut9 x = unsafeCoerce# x
+{-# INLINE happyOut9 #-}
+happyIn10 :: (Ast -> Ast) -> (HappyAbsSyn )
+happyIn10 x = unsafeCoerce# x
+{-# INLINE happyIn10 #-}
+happyOut10 :: (HappyAbsSyn ) -> (Ast -> Ast)
+happyOut10 x = unsafeCoerce# x
+{-# INLINE happyOut10 #-}
+happyIn11 :: (Ast -> Ast) -> (HappyAbsSyn )
+happyIn11 x = unsafeCoerce# x
+{-# INLINE happyIn11 #-}
+happyOut11 :: (HappyAbsSyn ) -> (Ast -> Ast)
+happyOut11 x = unsafeCoerce# x
+{-# INLINE happyOut11 #-}
+happyIn12 :: (Ast -> Ast) -> (HappyAbsSyn )
+happyIn12 x = unsafeCoerce# x
+{-# INLINE happyIn12 #-}
+happyOut12 :: (HappyAbsSyn ) -> (Ast -> Ast)
+happyOut12 x = unsafeCoerce# x
+{-# INLINE happyOut12 #-}
+happyIn13 :: (Ast -> Ast) -> (HappyAbsSyn )
+happyIn13 x = unsafeCoerce# x
+{-# INLINE happyIn13 #-}
+happyOut13 :: (HappyAbsSyn ) -> (Ast -> Ast)
+happyOut13 x = unsafeCoerce# x
+{-# INLINE happyOut13 #-}
+happyIn14 :: (( Ast -> Ast, Ast -> Ast )) -> (HappyAbsSyn )
+happyIn14 x = unsafeCoerce# x
+{-# INLINE happyIn14 #-}
+happyOut14 :: (HappyAbsSyn ) -> (( Ast -> Ast, Ast -> Ast ))
+happyOut14 x = unsafeCoerce# x
+{-# INLINE happyOut14 #-}
+happyIn15 :: (( [ Ast ], [ Ast ] )) -> (HappyAbsSyn )
+happyIn15 x = unsafeCoerce# x
+{-# INLINE happyIn15 #-}
+happyOut15 :: (HappyAbsSyn ) -> (( [ Ast ], [ Ast ] ))
+happyOut15 x = unsafeCoerce# x
+{-# INLINE happyOut15 #-}
+happyIn16 :: (Ast) -> (HappyAbsSyn )
+happyIn16 x = unsafeCoerce# x
+{-# INLINE happyIn16 #-}
+happyOut16 :: (HappyAbsSyn ) -> (Ast)
+happyOut16 x = unsafeCoerce# x
+{-# INLINE happyOut16 #-}
+happyIn17 :: (Ast) -> (HappyAbsSyn )
+happyIn17 x = unsafeCoerce# x
+{-# INLINE happyIn17 #-}
+happyOut17 :: (HappyAbsSyn ) -> (Ast)
+happyOut17 x = unsafeCoerce# x
+{-# INLINE happyOut17 #-}
+happyIn18 :: (Ast) -> (HappyAbsSyn )
+happyIn18 x = unsafeCoerce# x
+{-# INLINE happyIn18 #-}
+happyOut18 :: (HappyAbsSyn ) -> (Ast)
+happyOut18 x = unsafeCoerce# x
+{-# INLINE happyOut18 #-}
+happyIn19 :: ([ Ast ]) -> (HappyAbsSyn )
+happyIn19 x = unsafeCoerce# x
+{-# INLINE happyIn19 #-}
+happyOut19 :: (HappyAbsSyn ) -> ([ Ast ])
+happyOut19 x = unsafeCoerce# x
+{-# INLINE happyOut19 #-}
+happyIn20 :: ([ Ast ]) -> (HappyAbsSyn )
+happyIn20 x = unsafeCoerce# x
+{-# INLINE happyIn20 #-}
+happyOut20 :: (HappyAbsSyn ) -> ([ Ast ])
+happyOut20 x = unsafeCoerce# x
+{-# INLINE happyOut20 #-}
+happyIn21 :: (Ast) -> (HappyAbsSyn )
+happyIn21 x = unsafeCoerce# x
+{-# INLINE happyIn21 #-}
+happyOut21 :: (HappyAbsSyn ) -> (Ast)
+happyOut21 x = unsafeCoerce# x
+{-# INLINE happyOut21 #-}
+happyIn22 :: ([Ast]) -> (HappyAbsSyn )
+happyIn22 x = unsafeCoerce# x
+{-# INLINE happyIn22 #-}
+happyOut22 :: (HappyAbsSyn ) -> ([Ast])
+happyOut22 x = unsafeCoerce# x
+{-# INLINE happyOut22 #-}
+happyIn23 :: ([ Ast ]) -> (HappyAbsSyn )
+happyIn23 x = unsafeCoerce# x
+{-# INLINE happyIn23 #-}
+happyOut23 :: (HappyAbsSyn ) -> ([ Ast ])
+happyOut23 x = unsafeCoerce# x
+{-# INLINE happyOut23 #-}
+happyIn24 :: (Ast) -> (HappyAbsSyn )
+happyIn24 x = unsafeCoerce# x
+{-# INLINE happyIn24 #-}
+happyOut24 :: (HappyAbsSyn ) -> (Ast)
+happyOut24 x = unsafeCoerce# x
+{-# INLINE happyOut24 #-}
+happyIn25 :: (Ast -> Ast) -> (HappyAbsSyn )
+happyIn25 x = unsafeCoerce# x
+{-# INLINE happyIn25 #-}
+happyOut25 :: (HappyAbsSyn ) -> (Ast -> Ast)
+happyOut25 x = unsafeCoerce# x
+{-# INLINE happyOut25 #-}
+happyIn26 :: (Ast -> Ast) -> (HappyAbsSyn )
+happyIn26 x = unsafeCoerce# x
+{-# INLINE happyIn26 #-}
+happyOut26 :: (HappyAbsSyn ) -> (Ast -> Ast)
+happyOut26 x = unsafeCoerce# x
+{-# INLINE happyOut26 #-}
+happyIn27 :: (String -> Ast -> [ Ast ]) -> (HappyAbsSyn )
+happyIn27 x = unsafeCoerce# x
+{-# INLINE happyIn27 #-}
+happyOut27 :: (HappyAbsSyn ) -> (String -> Ast -> [ Ast ])
+happyOut27 x = unsafeCoerce# x
+{-# INLINE happyOut27 #-}
+happyIn28 :: (String -> Ast -> Ast) -> (HappyAbsSyn )
+happyIn28 x = unsafeCoerce# x
+{-# INLINE happyIn28 #-}
+happyOut28 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)
+happyOut28 x = unsafeCoerce# x
+{-# INLINE happyOut28 #-}
+happyIn29 :: (String -> Ast -> Ast) -> (HappyAbsSyn )
+happyIn29 x = unsafeCoerce# x
+{-# INLINE happyIn29 #-}
+happyOut29 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)
+happyOut29 x = unsafeCoerce# x
+{-# INLINE happyOut29 #-}
+happyInTok :: Token -> (HappyAbsSyn )
+happyInTok x = unsafeCoerce# x
+{-# INLINE happyInTok #-}
+happyOutTok :: (HappyAbsSyn ) -> Token
+happyOutTok x = unsafeCoerce# x
+{-# INLINE happyOutTok #-}
+
+
+happyActOffsets :: HappyAddr
+happyActOffsets = HappyA# "\xce\x00\xce\x00\x00\x00\x00\x00\x47\x02\x9c\x00\x00\x00\x00\x00\x40\x00\x00\x00\x06\x00\x00\x00\xfd\xff\x00\x00\x00\x00\x7e\x01\x7e\x01\x13\x01\x89\x00\x13\x01\x13\x01\x13\x01\x00\x00\x68\x01\x13\x01\x5f\x01\x5f\x01\x1c\x00\x17\x00\x63\x00\x97\x01\xa9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xff\x5c\x01\x00\x00\x44\x00\x64\x01\x5b\x01\xff\xff\xfd\xff\x43\x01\x13\x01\x71\x01\x41\x01\x13\x01\x6f\x01\x4c\x01\x4b\x01\xec\xff\x2a\x01\x00\x00\x3c\x01\x00\x00\x00\x00\x47\x02\x64\x00\x10\x00\x00\x00\x73\x01\x3a\x00\x38\x00\x1b\x01\x00\x00\x13\x01\x28\x00\x13\x01\x00\x00\x16\x00\x00\x00\x23\x01\x0f\x01\x0f\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x63\x02\x63\x02\x63\x02\x95\x02\x63\x02\x7c\x02\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x08\x01\x08\x01\x56\x08\x47\x02\x24\x01\x22\x01\x4e\x01\x14\x01\x00\x00\xfa\xff\x13\x01\x01\x00\xfb\xff\x12\x01\x00\x00\x00\x00\x59\x00\x3a\x01\x63\x00\x62\x00\x00\x00\xb7\x01\x00\x00\xf9\x00\x13\x01\x13\x01\x13\x01\x00\x00\x13\x01\x00\x00\x00\x01\x25\x01\x13\x01\xf4\x00\xf4\x00\x13\x01\x13\x01\x2b\x02\x29\x01\x13\x01\x0e\x02\x27\x01\xef\x00\x0e\x00\x00\x00\x03\x01\x1e\x01\xe3\x00\x00\x00\x0c\x00\x13\x01\x00\x00\x00\x00\x1a\x01\x57\x00\x00\x00\x19\x01\x51\x00\x47\x02\xf0\x00\xe6\x00\x47\x02\xfc\xff\xfb\x00\x47\x02\x96\x01\x47\x02\x47\x02\xe8\xff\x00\x00\xf8\x00\x63\x00\xf8\x00\x00\x00\xf5\x00\x4f\x00\x00\x00\x13\x01\xc2\x00\x00\x00\x00\x00\x13\x01\x13\x01\x47\x02\x4d\x01\xdb\x00\xd9\x00\x49\x00\x00\x00\x00\x00\xe7\x00\x13\x01\xa1\x00\x13\x01\xfc\xff\x00\x00\x13\x01\x13\x01\x00\x00\x13\x01\x00\x00\x13\x01\x47\x02\x08\x00\x00\x00\xcf\x00\x13\x01\xca\x00\x85\x00\x24\x00\x12\x00\x47\x02\x47\x02\x00\x00\x47\x02\x97\x00\x47\x02\x00\x00\x00\x00\x13\x01\x00\x00\x00\x00\x00\x00\x4d\x01\x13\x01\x00\x00\x00\x00\x00\x00\x13\x01\xf1\x01\x00\x00\xd4\x01\x47\x02\x00\x00\x00\x00\x00\x00"#
+
+happyGotoOffsets :: HappyAddr
+happyGotoOffsets = HappyA# "\xa7\x00\x31\x01\x00\x00\x00\x00\x00\x00\xb1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x01\x00\x00\x00\x00\xd8\x00\xd1\x00\x4a\x08\x9e\x03\x87\x03\x33\x08\x1c\x08\x00\x00\x00\x00\x05\x08\xc1\x00\x7f\x00\x00\x00\x00\x00\xf3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec\x00\x00\x00\xb4\x00\x70\x03\xdf\x00\x00\x00\xee\x07\x00\x00\x00\x00\xd7\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\xc0\x07\xd3\x00\x59\x03\x00\x00\x0d\x00\x00\x00\x9f\x00\x8e\x00\x71\x00\xa9\x07\x92\x07\x7b\x07\x64\x07\x4d\x07\x36\x07\x1f\x07\x08\x07\xf1\x06\xda\x06\xc3\x06\xac\x06\x95\x06\x7e\x06\x67\x06\x50\x06\x39\x06\x22\x06\x0b\x06\xf4\x05\xdd\x05\xc6\x05\xaf\x05\x98\x05\x81\x05\x6a\x05\x53\x05\x3c\x05\x25\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x00\x42\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x00\xc9\x00\x00\x00\x00\x00\x00\x00\x9b\x00\x0e\x05\xf7\x04\xe0\x04\x00\x00\xc9\x04\x00\x00\x00\x00\x00\x00\xb2\x04\x93\x00\x77\x00\x9b\x04\x2b\x03\x00\x00\x00\x00\x14\x03\x00\x00\x00\x00\xf5\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x84\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\x02\x00\x00\x00\x00\x00\x00\xe6\x02\x6d\x04\x00\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x04\x20\x00\x3f\x04\x4d\x00\x00\x00\x28\x04\x11\x04\x00\x00\xcf\x02\x00\x00\xb8\x02\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\x03\x00\x00\x00\x00\x00\x00\x1f\x00\xcc\x03\x00\x00\x00\x00\x00\x00\xb5\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+
+happyDefActions :: HappyAddr
+happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x8b\xff\xfa\xff\xbd\xff\xed\xff\xee\xff\x00\x00\xcd\xff\xa2\xff\xef\xff\x9b\xff\x90\xff\x8e\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xff\x00\x00\x8a\xff\xf4\xff\xcc\xff\xcb\xff\xa1\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xff\x00\x00\xc8\xff\xce\xff\xac\xff\xcf\xff\xd0\xff\xca\xff\x00\x00\x00\x00\x88\xff\x00\x00\x00\x00\x00\x00\x99\xff\x97\xff\x00\x00\x00\x00\x00\x00\x9f\xff\x00\x00\xb1\xff\xbb\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xeb\xff\xec\xff\xbe\xff\xc5\xff\xc6\xff\x00\x00\x00\x00\xa7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\xff\xa9\xff\x00\x00\x95\xff\x00\x00\x00\x00\x91\xff\x00\x00\x96\xff\x00\x00\x00\x00\x00\x00\x00\x00\x89\xff\x00\x00\xa0\xff\xab\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\xff\x00\x00\x86\xff\x00\x00\x00\x00\xfc\xff\xfb\xff\x00\x00\x00\x00\x87\xff\xb4\xff\x00\x00\x00\x00\xb5\xff\x00\x00\x00\x00\xc0\xff\x00\x00\x00\x00\xc4\xff\x00\x00\x00\x00\xc9\xff\x00\x00\xf1\xff\xf2\xff\x00\x00\x8f\xff\x93\xff\x00\x00\x94\xff\x9e\xff\x00\x00\x00\x00\xa3\xff\x00\x00\x00\x00\xa4\xff\xa5\xff\x00\x00\x00\x00\xf3\xff\xb6\xff\xbc\xff\x00\x00\x00\x00\xaa\xff\xb2\xff\x92\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9d\xff\x00\x00\x00\x00\xae\xff\x00\x00\xad\xff\x00\x00\xf9\xff\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xff\xc3\xff\x9c\xff\xf0\xff\x00\x00\xc2\xff\xa6\xff\xb3\xff\x00\x00\xba\xff\xb8\xff\xb7\xff\xb6\xff\x00\x00\xb0\xff\xaf\xff\xf5\xff\x00\x00\x00\x00\xf7\xff\x00\x00\xc1\xff\xb9\xff\xf8\xff"#
+
+happyCheck :: HappyAddr
+happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x07\x00\x0b\x00\x0b\x00\x0b\x00\x09\x00\x0a\x00\x0b\x00\x16\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x16\x00\x0b\x00\x0a\x00\x2b\x00\x03\x00\x16\x00\x0a\x00\x2b\x00\x0a\x00\x41\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x0c\x00\x47\x00\x09\x00\x0b\x00\x0b\x00\x03\x00\x25\x00\x09\x00\x3e\x00\x0b\x00\x29\x00\x2a\x00\x3e\x00\x0c\x00\x16\x00\x33\x00\x34\x00\x35\x00\x0c\x00\x09\x00\x33\x00\x34\x00\x2c\x00\x3a\x00\x39\x00\x38\x00\x10\x00\x3a\x00\x2c\x00\x3a\x00\x2c\x00\x43\x00\x2c\x00\x40\x00\x46\x00\x42\x00\x46\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x33\x00\x34\x00\x35\x00\x46\x00\x09\x00\x42\x00\x0b\x00\x2c\x00\x3a\x00\x0e\x00\x0f\x00\x10\x00\x0c\x00\x3a\x00\x0c\x00\x18\x00\x43\x00\x16\x00\x0c\x00\x46\x00\x0c\x00\x11\x00\x12\x00\x38\x00\x39\x00\x3a\x00\x0c\x00\x2c\x00\x0c\x00\x2c\x00\x3f\x00\x40\x00\x25\x00\x42\x00\x09\x00\x09\x00\x29\x00\x2a\x00\x37\x00\x0c\x00\x37\x00\x10\x00\x10\x00\x03\x00\x2c\x00\x36\x00\x33\x00\x34\x00\x08\x00\x03\x00\x2c\x00\x38\x00\x2c\x00\x3a\x00\x3b\x00\x11\x00\x12\x00\x03\x00\x2c\x00\x40\x00\x2c\x00\x42\x00\x08\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x02\x00\x03\x00\x2c\x00\x03\x00\x09\x00\x0a\x00\x0b\x00\x07\x00\x03\x00\x0e\x00\x0f\x00\x10\x00\x38\x00\x03\x00\x3a\x00\x3a\x00\x03\x00\x16\x00\x0e\x00\x0f\x00\x40\x00\x40\x00\x42\x00\x42\x00\x16\x00\x00\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x13\x00\x06\x00\x25\x00\x17\x00\x18\x00\x19\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x03\x00\x11\x00\x12\x00\x09\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x2b\x00\x3a\x00\x03\x00\x29\x00\x2a\x00\x42\x00\x07\x00\x40\x00\x2e\x00\x42\x00\x03\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x03\x00\x03\x00\x0b\x00\x03\x00\x09\x00\x07\x00\x0b\x00\x0b\x00\x03\x00\x0e\x00\x0f\x00\x10\x00\x07\x00\x17\x00\x18\x00\x19\x00\x42\x00\x16\x00\x3c\x00\x3d\x00\x17\x00\x18\x00\x19\x00\x17\x00\x18\x00\x19\x00\x01\x00\x07\x00\x03\x00\x04\x00\x18\x00\x06\x00\x25\x00\x15\x00\x16\x00\x03\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x3a\x00\x11\x00\x12\x00\x07\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x2c\x00\x3a\x00\x3b\x00\x17\x00\x18\x00\x19\x00\x18\x00\x40\x00\x14\x00\x42\x00\x2b\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x10\x00\x11\x00\x12\x00\x13\x00\x09\x00\x2d\x00\x0b\x00\x15\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x0b\x00\x43\x00\x09\x00\x39\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x2d\x00\x0a\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x42\x00\x06\x00\x25\x00\x14\x00\x3a\x00\x42\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x07\x00\x11\x00\x12\x00\x30\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x3a\x00\x3a\x00\x2c\x00\x01\x00\x2c\x00\x42\x00\x2f\x00\x40\x00\x39\x00\x42\x00\x2c\x00\x44\x00\x45\x00\x46\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x3a\x00\x2c\x00\x05\x00\x2d\x00\x0b\x00\x3a\x00\x0b\x00\x3a\x00\x31\x00\x32\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x06\x00\x42\x00\x3a\x00\x43\x00\x09\x00\x42\x00\x3a\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x08\x00\x42\x00\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\xff\xff\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\xff\xff\x25\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\x0b\x00\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
+
+happyTable :: HappyAddr
+happyTable = HappyA# "\x00\x00\x10\x00\x11\x00\x12\x00\x45\x00\xd1\x00\x2f\x00\x14\x00\x13\x00\xb0\x00\x14\x00\x99\x00\x32\x00\x15\x00\x16\x00\x17\x00\x18\x00\x47\x00\xef\x00\xdf\x00\x02\x01\x18\x00\xed\x00\xa4\x00\xb7\x00\x29\x00\x9f\x00\x8b\x00\x08\x00\x8c\x00\x01\x01\xff\xff\x2e\x00\x8e\x00\x2f\x00\xf6\x00\x19\x00\x31\x00\xe0\x00\x32\x00\x1a\x00\x1b\x00\xa5\x00\x08\x01\x18\x00\x8f\x00\x90\x00\xd2\x00\x02\x01\x13\x00\x1c\x00\x1d\x00\xf0\x00\x30\x00\x46\x00\x1e\x00\x17\x00\x1f\x00\xa0\x00\x33\x00\xa0\x00\xd3\x00\xa0\x00\x21\x00\xd4\x00\x22\x00\x25\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x8f\x00\x90\x00\x91\x00\x48\x00\x13\x00\x22\x00\x14\x00\xa0\x00\x30\x00\x15\x00\x16\x00\x17\x00\xf9\x00\x33\x00\xfb\x00\x49\x00\x92\x00\x18\x00\xdc\x00\x93\x00\xe6\x00\xf4\x00\x0a\x00\x96\x00\x97\x00\x1f\x00\xe8\x00\x9b\x00\xcd\x00\x9b\x00\x98\x00\x21\x00\x19\x00\x22\x00\x13\x00\x13\x00\x1a\x00\x1b\x00\x9c\x00\xa1\x00\x9d\x00\x17\x00\x17\x00\x33\x00\xa0\x00\x4a\x00\x1c\x00\x1d\x00\x87\x00\xbe\x00\xa0\x00\x1e\x00\xa0\x00\x1f\x00\x20\x00\xe2\x00\x0a\x00\x33\x00\xa0\x00\x21\x00\xa0\x00\x22\x00\x34\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\xea\x00\xeb\x00\xa0\x00\x35\x00\x13\x00\x3f\x00\x14\x00\x88\x00\xbf\x00\x15\x00\x16\x00\x17\x00\xcb\x00\x03\x00\x1f\x00\x1f\x00\xc7\x00\x18\x00\xcf\x00\x08\x00\x21\x00\x21\x00\x22\x00\x22\x00\x99\x00\x25\x00\x26\x00\x89\x00\x03\x00\x04\x00\xa1\x00\x05\x00\x19\x00\xdd\x00\x0d\x00\x0e\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\xb0\x00\x09\x00\x0a\x00\x4a\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\x00\x01\x1f\x00\x35\x00\x4c\x00\x4d\x00\x22\x00\x36\x00\x21\x00\x4e\x00\x22\x00\x03\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x03\x00\x35\x00\x04\x01\x03\x00\x13\x00\x40\x00\x14\x00\xee\x00\x35\x00\x15\x00\x16\x00\x17\x00\x41\x00\xc9\x00\x0d\x00\x0e\x00\x22\x00\x18\x00\x2a\x00\x2b\x00\xcb\x00\x0d\x00\x0e\x00\x94\x00\x0d\x00\x0e\x00\xb2\x00\x45\x00\x03\x00\x04\x00\xfa\x00\x05\x00\x19\x00\xad\x00\x43\x00\x03\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\xda\x00\x09\x00\x0a\x00\x45\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\xfb\x00\x1f\x00\x20\x00\x2c\x00\x0d\x00\x0e\x00\xdd\x00\x21\x00\xe2\x00\x22\x00\xe4\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x52\x00\x53\x00\x54\x00\x55\x00\x13\x00\xe5\x00\x14\x00\x42\x00\x43\x00\x15\x00\x16\x00\x17\x00\xe7\x00\xe9\x00\xb4\x00\xb5\x00\x46\x00\x18\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xb6\x00\xb8\x00\x02\x00\xbb\x00\x03\x00\x04\x00\x22\x00\x05\x00\x19\x00\xc2\x00\xc3\x00\x22\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\x45\x00\x09\x00\x0a\x00\xd5\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\xce\x00\x1f\x00\x9b\x00\xd6\x00\xa6\x00\x22\x00\x8b\x00\x21\x00\x46\x00\x22\x00\x9b\x00\x23\x00\x24\x00\x25\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xa3\x00\xa6\x00\x9e\x00\xa7\x00\xa8\x00\xaa\x00\xab\x00\xad\x00\xfd\x00\xfe\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xe1\x00\x22\x00\xb2\x00\x28\x00\x2c\x00\x22\x00\x39\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xc9\x00\x22\x00\x00\x00\x00\x00\x00\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x0a\x01\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x06\x01\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xb9\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xbc\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x00\x00\x67\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x00\x00\x00\x00\x00\x00\x03\x00\x3b\x00\xf0\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xf1\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xd7\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xda\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xb9\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xbc\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xce\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x93\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xae\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x3c\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x3d\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x06\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x07\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xfe\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x04\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf2\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf3\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf7\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xd6\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xe9\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xbd\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc0\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc3\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc4\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc6\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6b\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6c\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6d\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x70\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x71\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x72\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x73\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x74\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x75\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x76\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x77\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x78\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x79\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7b\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7c\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7d\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x80\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x81\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x82\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x83\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x84\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x85\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x86\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x98\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xa8\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xab\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x37\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x39\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+
+happyReduceArr = array (1, 121) [
+	(1 , happyReduce_1),
+	(2 , happyReduce_2),
+	(3 , happyReduce_3),
+	(4 , happyReduce_4),
+	(5 , happyReduce_5),
+	(6 , happyReduce_6),
+	(7 , happyReduce_7),
+	(8 , happyReduce_8),
+	(9 , happyReduce_9),
+	(10 , happyReduce_10),
+	(11 , happyReduce_11),
+	(12 , happyReduce_12),
+	(13 , happyReduce_13),
+	(14 , happyReduce_14),
+	(15 , happyReduce_15),
+	(16 , happyReduce_16),
+	(17 , happyReduce_17),
+	(18 , happyReduce_18),
+	(19 , happyReduce_19),
+	(20 , happyReduce_20),
+	(21 , happyReduce_21),
+	(22 , happyReduce_22),
+	(23 , happyReduce_23),
+	(24 , happyReduce_24),
+	(25 , happyReduce_25),
+	(26 , happyReduce_26),
+	(27 , happyReduce_27),
+	(28 , happyReduce_28),
+	(29 , happyReduce_29),
+	(30 , happyReduce_30),
+	(31 , happyReduce_31),
+	(32 , happyReduce_32),
+	(33 , happyReduce_33),
+	(34 , happyReduce_34),
+	(35 , happyReduce_35),
+	(36 , happyReduce_36),
+	(37 , happyReduce_37),
+	(38 , happyReduce_38),
+	(39 , happyReduce_39),
+	(40 , happyReduce_40),
+	(41 , happyReduce_41),
+	(42 , happyReduce_42),
+	(43 , happyReduce_43),
+	(44 , happyReduce_44),
+	(45 , happyReduce_45),
+	(46 , happyReduce_46),
+	(47 , happyReduce_47),
+	(48 , happyReduce_48),
+	(49 , happyReduce_49),
+	(50 , happyReduce_50),
+	(51 , happyReduce_51),
+	(52 , happyReduce_52),
+	(53 , happyReduce_53),
+	(54 , happyReduce_54),
+	(55 , happyReduce_55),
+	(56 , happyReduce_56),
+	(57 , happyReduce_57),
+	(58 , happyReduce_58),
+	(59 , happyReduce_59),
+	(60 , happyReduce_60),
+	(61 , happyReduce_61),
+	(62 , happyReduce_62),
+	(63 , happyReduce_63),
+	(64 , happyReduce_64),
+	(65 , happyReduce_65),
+	(66 , happyReduce_66),
+	(67 , happyReduce_67),
+	(68 , happyReduce_68),
+	(69 , happyReduce_69),
+	(70 , happyReduce_70),
+	(71 , happyReduce_71),
+	(72 , happyReduce_72),
+	(73 , happyReduce_73),
+	(74 , happyReduce_74),
+	(75 , happyReduce_75),
+	(76 , happyReduce_76),
+	(77 , happyReduce_77),
+	(78 , happyReduce_78),
+	(79 , happyReduce_79),
+	(80 , happyReduce_80),
+	(81 , happyReduce_81),
+	(82 , happyReduce_82),
+	(83 , happyReduce_83),
+	(84 , happyReduce_84),
+	(85 , happyReduce_85),
+	(86 , happyReduce_86),
+	(87 , happyReduce_87),
+	(88 , happyReduce_88),
+	(89 , happyReduce_89),
+	(90 , happyReduce_90),
+	(91 , happyReduce_91),
+	(92 , happyReduce_92),
+	(93 , happyReduce_93),
+	(94 , happyReduce_94),
+	(95 , happyReduce_95),
+	(96 , happyReduce_96),
+	(97 , happyReduce_97),
+	(98 , happyReduce_98),
+	(99 , happyReduce_99),
+	(100 , happyReduce_100),
+	(101 , happyReduce_101),
+	(102 , happyReduce_102),
+	(103 , happyReduce_103),
+	(104 , happyReduce_104),
+	(105 , happyReduce_105),
+	(106 , happyReduce_106),
+	(107 , happyReduce_107),
+	(108 , happyReduce_108),
+	(109 , happyReduce_109),
+	(110 , happyReduce_110),
+	(111 , happyReduce_111),
+	(112 , happyReduce_112),
+	(113 , happyReduce_113),
+	(114 , happyReduce_114),
+	(115 , happyReduce_115),
+	(116 , happyReduce_116),
+	(117 , happyReduce_117),
+	(118 , happyReduce_118),
+	(119 , happyReduce_119),
+	(120 , happyReduce_120),
+	(121 , happyReduce_121)
+	]
+
+happy_n_terms = 72 :: Int
+happy_n_nonterms = 26 :: Int
+
+happyReduce_1 = happySpecReduce_1  0# happyReduction_1
+happyReduction_1 happy_x_1
+	 =  case happyOut5 happy_x_1 of { happy_var_1 -> 
+	happyIn4
+		 ([happy_var_1]
+	)}
+
+happyReduce_2 = happySpecReduce_2  0# happyReduction_2
+happyReduction_2 happy_x_2
+	happy_x_1
+	 =  case happyOut5 happy_x_1 of { happy_var_1 -> 
+	happyIn4
+		 ([happy_var_1]
+	)}
+
+happyReduce_3 = happySpecReduce_3  0# happyReduction_3
+happyReduction_3 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut4 happy_x_1 of { happy_var_1 -> 
+	case happyOut5 happy_x_3 of { happy_var_3 -> 
+	happyIn4
+		 (happy_var_1++[happy_var_3]
+	)}}
+
+happyReduce_4 = happyReduce 4# 0# happyReduction_4
+happyReduction_4 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut4 happy_x_1 of { happy_var_1 -> 
+	case happyOut5 happy_x_3 of { happy_var_3 -> 
+	happyIn4
+		 (happy_var_1++[happy_var_3]
+	) `HappyStk` happyRest}}
+
+happyReduce_5 = happySpecReduce_1  1# happyReduction_5
+happyReduction_5 happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	happyIn5
+		 (happy_var_1
+	)}
+
+happyReduce_6 = happyReduce 5# 1# happyReduction_6
+happyReduction_6 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut7 happy_x_3 of { happy_var_3 -> 
+	case happyOut8 happy_x_5 of { happy_var_5 -> 
+	happyIn5
+		 (Ast "variable" [happy_var_3,happy_var_5]
+	) `HappyStk` happyRest}}
+
+happyReduce_7 = happyReduce 9# 1# happyReduction_7
+happyReduction_7 (happy_x_9 `HappyStk`
+	happy_x_8 `HappyStk`
+	happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_3 of { (QName happy_var_3) -> 
+	case happyOut6 happy_x_5 of { happy_var_5 -> 
+	case happyOut8 happy_x_8 of { happy_var_8 -> 
+	happyIn5
+		 (Ast "function" ([Avar happy_var_3,happy_var_8]++happy_var_5)
+	) `HappyStk` happyRest}}}
+
+happyReduce_8 = happyReduce 8# 1# happyReduction_8
+happyReduction_8 (happy_x_8 `HappyStk`
+	happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_3 of { (QName happy_var_3) -> 
+	case happyOut8 happy_x_7 of { happy_var_7 -> 
+	happyIn5
+		 (Ast "function" [Avar happy_var_3,happy_var_7]
+	) `HappyStk` happyRest}}
+
+happyReduce_9 = happySpecReduce_1  2# happyReduction_9
+happyReduction_9 happy_x_1
+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
+	happyIn6
+		 ([happy_var_1]
+	)}
+
+happyReduce_10 = happySpecReduce_3  2# happyReduction_10
+happyReduction_10 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut6 happy_x_1 of { happy_var_1 -> 
+	case happyOut7 happy_x_3 of { happy_var_3 -> 
+	happyIn6
+		 (happy_var_1++[happy_var_3]
+	)}}
+
+happyReduce_11 = happySpecReduce_1  3# happyReduction_11
+happyReduction_11 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (Variable happy_var_1) -> 
+	happyIn7
+		 (Avar happy_var_1
+	)}
+
+happyReduce_12 = happyReduce 5# 4# happyReduction_12
+happyReduction_12 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut10 happy_x_1 of { happy_var_1 -> 
+	case happyOut13 happy_x_2 of { happy_var_2 -> 
+	case happyOut14 happy_x_3 of { happy_var_3 -> 
+	case happyOut8 happy_x_5 of { happy_var_5 -> 
+	happyIn8
+		 ((snd happy_var_3) (happy_var_1 (happy_var_2 ((fst happy_var_3) happy_var_5)))
+	) `HappyStk` happyRest}}}}
+
+happyReduce_13 = happyReduce 4# 4# happyReduction_13
+happyReduction_13 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_2 of { happy_var_2 -> 
+	case happyOut8 happy_x_4 of { happy_var_4 -> 
+	happyIn8
+		 (call "some" [happy_var_2 happy_var_4]
+	) `HappyStk` happyRest}}
+
+happyReduce_14 = happyReduce 4# 4# happyReduction_14
+happyReduction_14 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_2 of { happy_var_2 -> 
+	case happyOut8 happy_x_4 of { happy_var_4 -> 
+	happyIn8
+		 (call "not" [call "some" [happy_var_2 (call "not" [happy_var_4])]]
+	) `HappyStk` happyRest}}
+
+happyReduce_15 = happyReduce 6# 4# happyReduction_15
+happyReduction_15 (happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut8 happy_x_2 of { happy_var_2 -> 
+	case happyOut8 happy_x_4 of { happy_var_4 -> 
+	case happyOut8 happy_x_6 of { happy_var_6 -> 
+	happyIn8
+		 (call "if" [happy_var_2,happy_var_4,happy_var_6]
+	) `HappyStk` happyRest}}}
+
+happyReduce_16 = happySpecReduce_1  4# happyReduction_16
+happyReduction_16 happy_x_1
+	 =  case happyOut24 happy_x_1 of { happy_var_1 -> 
+	happyIn8
+		 (happy_var_1
+	)}
+
+happyReduce_17 = happySpecReduce_1  4# happyReduction_17
+happyReduction_17 happy_x_1
+	 =  case happyOut18 happy_x_1 of { happy_var_1 -> 
+	happyIn8
+		 (happy_var_1
+	)}
+
+happyReduce_18 = happySpecReduce_1  4# happyReduction_18
+happyReduction_18 happy_x_1
+	 =  case happyOut17 happy_x_1 of { happy_var_1 -> 
+	happyIn8
+		 (happy_var_1
+	)}
+
+happyReduce_19 = happySpecReduce_3  4# happyReduction_19
+happyReduction_19 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "to" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_20 = happySpecReduce_3  4# happyReduction_20
+happyReduction_20 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "+" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_21 = happySpecReduce_3  4# happyReduction_21
+happyReduction_21 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "-" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_22 = happySpecReduce_3  4# happyReduction_22
+happyReduction_22 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "*" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_23 = happySpecReduce_3  4# happyReduction_23
+happyReduction_23 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "div" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_24 = happySpecReduce_3  4# happyReduction_24
+happyReduction_24 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "idiv" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_25 = happySpecReduce_3  4# happyReduction_25
+happyReduction_25 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "mod" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_26 = happySpecReduce_3  4# happyReduction_26
+happyReduction_26 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "=" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_27 = happySpecReduce_3  4# happyReduction_27
+happyReduction_27 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "!=" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_28 = happySpecReduce_3  4# happyReduction_28
+happyReduction_28 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "<" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_29 = happySpecReduce_3  4# happyReduction_29
+happyReduction_29 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "<=" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_30 = happySpecReduce_3  4# happyReduction_30
+happyReduction_30 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call ">" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_31 = happySpecReduce_3  4# happyReduction_31
+happyReduction_31 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call ">=" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_32 = happySpecReduce_3  4# happyReduction_32
+happyReduction_32 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "<<" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_33 = happySpecReduce_3  4# happyReduction_33
+happyReduction_33 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call ">>" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_34 = happySpecReduce_3  4# happyReduction_34
+happyReduction_34 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "is" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_35 = happySpecReduce_3  4# happyReduction_35
+happyReduction_35 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "eq" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_36 = happySpecReduce_3  4# happyReduction_36
+happyReduction_36 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "ne" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_37 = happySpecReduce_3  4# happyReduction_37
+happyReduction_37 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "lt" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_38 = happySpecReduce_3  4# happyReduction_38
+happyReduction_38 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "le" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_39 = happySpecReduce_3  4# happyReduction_39
+happyReduction_39 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "gt" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_40 = happySpecReduce_3  4# happyReduction_40
+happyReduction_40 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "ge" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_41 = happySpecReduce_3  4# happyReduction_41
+happyReduction_41 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "and" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_42 = happySpecReduce_3  4# happyReduction_42
+happyReduction_42 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "or" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_43 = happySpecReduce_3  4# happyReduction_43
+happyReduction_43 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "not" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_44 = happySpecReduce_3  4# happyReduction_44
+happyReduction_44 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "union" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_45 = happySpecReduce_3  4# happyReduction_45
+happyReduction_45 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "intersect" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_46 = happySpecReduce_3  4# happyReduction_46
+happyReduction_46 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn8
+		 (call "except" [happy_var_1,happy_var_3]
+	)}}
+
+happyReduce_47 = happySpecReduce_2  4# happyReduction_47
+happyReduction_47 happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
+	happyIn8
+		 (call "uplus" [happy_var_2]
+	)}
+
+happyReduce_48 = happySpecReduce_2  4# happyReduction_48
+happyReduction_48 happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
+	happyIn8
+		 (call "uminus" [happy_var_2]
+	)}
+
+happyReduce_49 = happySpecReduce_2  4# happyReduction_49
+happyReduction_49 happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
+	happyIn8
+		 (call "not" [happy_var_2]
+	)}
+
+happyReduce_50 = happySpecReduce_1  4# happyReduction_50
+happyReduction_50 happy_x_1
+	 =  case happyOut21 happy_x_1 of { happy_var_1 -> 
+	happyIn8
+		 (happy_var_1
+	)}
+
+happyReduce_51 = happySpecReduce_1  4# happyReduction_51
+happyReduction_51 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TInteger happy_var_1) -> 
+	happyIn8
+		 (Aint happy_var_1
+	)}
+
+happyReduce_52 = happySpecReduce_1  4# happyReduction_52
+happyReduction_52 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TFloat happy_var_1) -> 
+	happyIn8
+		 (Afloat happy_var_1
+	)}
+
+happyReduce_53 = happySpecReduce_1  5# happyReduction_53
+happyReduction_53 happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	happyIn9
+		 ([happy_var_1]
+	)}
+
+happyReduce_54 = happySpecReduce_3  5# happyReduction_54
+happyReduction_54 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut9 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn9
+		 (happy_var_1++[happy_var_3]
+	)}}
+
+happyReduce_55 = happySpecReduce_2  6# happyReduction_55
+happyReduction_55 happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_2 of { happy_var_2 -> 
+	happyIn10
+		 (happy_var_2
+	)}
+
+happyReduce_56 = happySpecReduce_2  6# happyReduction_56
+happyReduction_56 happy_x_2
+	happy_x_1
+	 =  case happyOut12 happy_x_2 of { happy_var_2 -> 
+	happyIn10
+		 (happy_var_2
+	)}
+
+happyReduce_57 = happySpecReduce_3  6# happyReduction_57
+happyReduction_57 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut10 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn10
+		 (happy_var_1 . happy_var_3
+	)}}
+
+happyReduce_58 = happySpecReduce_3  6# happyReduction_58
+happyReduction_58 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut10 happy_x_1 of { happy_var_1 -> 
+	case happyOut12 happy_x_3 of { happy_var_3 -> 
+	happyIn10
+		 (happy_var_1 . happy_var_3
+	)}}
+
+happyReduce_59 = happySpecReduce_3  7# happyReduction_59
+happyReduction_59 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn11
+		 (\x -> Ast "for" [happy_var_1,Avar "$",happy_var_3,x]
+	)}}
+
+happyReduce_60 = happyReduce 5# 7# happyReduction_60
+happyReduction_60 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut7 happy_x_1 of { happy_var_1 -> 
+	case happyOut7 happy_x_3 of { happy_var_3 -> 
+	case happyOut8 happy_x_5 of { happy_var_5 -> 
+	happyIn11
+		 (\x -> Ast "for" [happy_var_1,happy_var_3,happy_var_5,x]
+	) `HappyStk` happyRest}}}
+
+happyReduce_61 = happyReduce 5# 7# happyReduction_61
+happyReduction_61 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut7 happy_x_3 of { happy_var_3 -> 
+	case happyOut8 happy_x_5 of { happy_var_5 -> 
+	happyIn11
+		 (\x -> happy_var_1(Ast "for" [happy_var_3,Avar "$",happy_var_5,x])
+	) `HappyStk` happyRest}}}
+
+happyReduce_62 = happyReduce 7# 7# happyReduction_62
+happyReduction_62 (happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut7 happy_x_3 of { happy_var_3 -> 
+	case happyOut7 happy_x_5 of { happy_var_5 -> 
+	case happyOut8 happy_x_7 of { happy_var_7 -> 
+	happyIn11
+		 (\x -> happy_var_1(Ast "for" [happy_var_3,happy_var_5,happy_var_7,x])
+	) `HappyStk` happyRest}}}}
+
+happyReduce_63 = happySpecReduce_3  8# happyReduction_63
+happyReduction_63 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn12
+		 (\x -> Ast "let" [happy_var_1,happy_var_3,x]
+	)}}
+
+happyReduce_64 = happyReduce 5# 8# happyReduction_64
+happyReduction_64 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut12 happy_x_1 of { happy_var_1 -> 
+	case happyOut7 happy_x_3 of { happy_var_3 -> 
+	case happyOut8 happy_x_5 of { happy_var_5 -> 
+	happyIn12
+		 (\x -> happy_var_1(Ast "let" [happy_var_3,happy_var_5,x])
+	) `HappyStk` happyRest}}}
+
+happyReduce_65 = happySpecReduce_2  9# happyReduction_65
+happyReduction_65 happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
+	happyIn13
+		 (\x -> Ast "predicate" [happy_var_2,x]
+	)}
+
+happyReduce_66 = happySpecReduce_0  9# happyReduction_66
+happyReduction_66  =  happyIn13
+		 (id
+	)
+
+happyReduce_67 = happySpecReduce_3  10# happyReduction_67
+happyReduction_67 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut15 happy_x_3 of { happy_var_3 -> 
+	happyIn14
+		 ((\x -> Ast "sortTuple" (x:(fst happy_var_3)),
+                                                           \x -> Ast "sort" (x:(snd happy_var_3)))
+	)}
+
+happyReduce_68 = happySpecReduce_0  10# happyReduction_68
+happyReduction_68  =  happyIn14
+		 ((id,id)
+	)
+
+happyReduce_69 = happySpecReduce_2  11# happyReduction_69
+happyReduction_69 happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut16 happy_x_2 of { happy_var_2 -> 
+	happyIn15
+		 (([happy_var_1],[happy_var_2])
+	)}}
+
+happyReduce_70 = happyReduce 4# 11# happyReduction_70
+happyReduction_70 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut15 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	case happyOut16 happy_x_4 of { happy_var_4 -> 
+	happyIn15
+		 (((fst happy_var_1)++[happy_var_3],(snd happy_var_1)++[happy_var_4])
+	) `HappyStk` happyRest}}}
+
+happyReduce_71 = happySpecReduce_1  12# happyReduction_71
+happyReduction_71 happy_x_1
+	 =  happyIn16
+		 (Avar "ascending"
+	)
+
+happyReduce_72 = happySpecReduce_1  12# happyReduction_72
+happyReduction_72 happy_x_1
+	 =  happyIn16
+		 (Avar "descending"
+	)
+
+happyReduce_73 = happySpecReduce_0  12# happyReduction_73
+happyReduction_73  =  happyIn16
+		 (Avar "ascending"
+	)
+
+happyReduce_74 = happyReduce 4# 13# happyReduction_74
+happyReduction_74 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_3 of { (QName happy_var_3) -> 
+	happyIn17
+		 (call "element" [Avar happy_var_3]
+	) `HappyStk` happyRest}
+
+happyReduce_75 = happyReduce 4# 13# happyReduction_75
+happyReduction_75 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_3 of { (QName happy_var_3) -> 
+	happyIn17
+		 (call "attribute" [Avar happy_var_3]
+	) `HappyStk` happyRest}
+
+happyReduce_76 = happyReduce 6# 14# happyReduction_76
+happyReduction_76 (happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut19 happy_x_1 of { happy_var_1 -> 
+	case happyOut20 happy_x_3 of { happy_var_3 -> 
+	case happyOutTok happy_x_5 of { (QName happy_var_5) -> 
+	happyIn18
+		 (if head happy_var_1 == Astring happy_var_5
+						  	     then Ast "element_construction" (happy_var_1++[Ast "append" happy_var_3])
+                                                          else parseError [TError ("Unmatched tags in element construction: "
+                                                                                   ++(show (head happy_var_1))++" '"++happy_var_5++"'")]
+	) `HappyStk` happyRest}}}
+
+happyReduce_77 = happyReduce 5# 14# happyReduction_77
+happyReduction_77 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut19 happy_x_1 of { happy_var_1 -> 
+	case happyOutTok happy_x_4 of { (QName happy_var_4) -> 
+	happyIn18
+		 (if head happy_var_1 == Astring happy_var_4
+							     then Ast "element_construction" (happy_var_1++[Ast "append" []])
+                                                          else parseError [TError ("Unmatched tags in element construction: "
+                                                                                   ++(show (head happy_var_1))++" '"++happy_var_4++"'")]
+	) `HappyStk` happyRest}}
+
+happyReduce_78 = happySpecReduce_2  14# happyReduction_78
+happyReduction_78 happy_x_2
+	happy_x_1
+	 =  case happyOut19 happy_x_1 of { happy_var_1 -> 
+	happyIn18
+		 (Ast "element_construction" (happy_var_1++[Ast "append" []])
+	)}
+
+happyReduce_79 = happyReduce 7# 14# happyReduction_79
+happyReduction_79 (happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut8 happy_x_3 of { happy_var_3 -> 
+	case happyOut9 happy_x_6 of { happy_var_6 -> 
+	happyIn18
+		 (Ast "element_construction" [happy_var_3,Ast "attributes" [],concatenateAll happy_var_6]
+	) `HappyStk` happyRest}}
+
+happyReduce_80 = happyReduce 7# 14# happyReduction_80
+happyReduction_80 (happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut8 happy_x_3 of { happy_var_3 -> 
+	case happyOut9 happy_x_6 of { happy_var_6 -> 
+	happyIn18
+		 (Ast "attribute_construction" [happy_var_3,concatenateAll happy_var_6]
+	) `HappyStk` happyRest}}
+
+happyReduce_81 = happyReduce 5# 14# happyReduction_81
+happyReduction_81 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
+	case happyOut9 happy_x_4 of { happy_var_4 -> 
+	happyIn18
+		 (Ast "element_construction" [Astring happy_var_2,Ast "attributes" [],concatenateAll happy_var_4]
+	) `HappyStk` happyRest}}
+
+happyReduce_82 = happyReduce 5# 14# happyReduction_82
+happyReduction_82 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
+	case happyOut9 happy_x_4 of { happy_var_4 -> 
+	happyIn18
+		 (Ast "attribute_construction" [Astring happy_var_2,concatenateAll happy_var_4]
+	) `HappyStk` happyRest}}
+
+happyReduce_83 = happySpecReduce_2  15# happyReduction_83
+happyReduction_83 happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
+	happyIn19
+		 ([Astring happy_var_2,Ast "attributes" []]
+	)}
+
+happyReduce_84 = happySpecReduce_3  15# happyReduction_84
+happyReduction_84 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
+	case happyOut23 happy_x_3 of { happy_var_3 -> 
+	happyIn19
+		 ([Astring happy_var_2,Ast "attributes" happy_var_3]
+	)}}
+
+happyReduce_85 = happySpecReduce_3  16# happyReduction_85
+happyReduction_85 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut9 happy_x_2 of { happy_var_2 -> 
+	happyIn20
+		 ([concatenateAll happy_var_2]
+	)}
+
+happyReduce_86 = happySpecReduce_1  16# happyReduction_86
+happyReduction_86 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TString happy_var_1) -> 
+	happyIn20
+		 ([Astring happy_var_1]
+	)}
+
+happyReduce_87 = happySpecReduce_1  16# happyReduction_87
+happyReduction_87 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (XMLtext happy_var_1) -> 
+	happyIn20
+		 ([Astring happy_var_1]
+	)}
+
+happyReduce_88 = happySpecReduce_1  16# happyReduction_88
+happyReduction_88 happy_x_1
+	 =  case happyOut18 happy_x_1 of { happy_var_1 -> 
+	happyIn20
+		 ([happy_var_1]
+	)}
+
+happyReduce_89 = happyReduce 4# 16# happyReduction_89
+happyReduction_89 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut20 happy_x_1 of { happy_var_1 -> 
+	case happyOut9 happy_x_3 of { happy_var_3 -> 
+	happyIn20
+		 (happy_var_1++[concatenateAll happy_var_3]
+	) `HappyStk` happyRest}}
+
+happyReduce_90 = happySpecReduce_2  16# happyReduction_90
+happyReduction_90 happy_x_2
+	happy_x_1
+	 =  case happyOut20 happy_x_1 of { happy_var_1 -> 
+	case happyOutTok happy_x_2 of { (TString happy_var_2) -> 
+	happyIn20
+		 (happy_var_1++[Astring happy_var_2]
+	)}}
+
+happyReduce_91 = happySpecReduce_2  16# happyReduction_91
+happyReduction_91 happy_x_2
+	happy_x_1
+	 =  case happyOut20 happy_x_1 of { happy_var_1 -> 
+	case happyOutTok happy_x_2 of { (XMLtext happy_var_2) -> 
+	happyIn20
+		 (happy_var_1++[Astring happy_var_2]
+	)}}
+
+happyReduce_92 = happySpecReduce_2  16# happyReduction_92
+happyReduction_92 happy_x_2
+	happy_x_1
+	 =  case happyOut20 happy_x_1 of { happy_var_1 -> 
+	case happyOut18 happy_x_2 of { happy_var_2 -> 
+	happyIn20
+		 (happy_var_1++[happy_var_2]
+	)}}
+
+happyReduce_93 = happySpecReduce_1  17# happyReduction_93
+happyReduction_93 happy_x_1
+	 =  case happyOut22 happy_x_1 of { happy_var_1 -> 
+	happyIn21
+		 (if length happy_var_1 == 1 then head happy_var_1 else Ast "append" happy_var_1
+	)}
+
+happyReduce_94 = happySpecReduce_1  18# happyReduction_94
+happyReduction_94 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TString happy_var_1) -> 
+	happyIn22
+		 (if happy_var_1=="" then [] else [Astring happy_var_1]
+	)}
+
+happyReduce_95 = happySpecReduce_3  18# happyReduction_95
+happyReduction_95 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut9 happy_x_2 of { happy_var_2 -> 
+	happyIn22
+		 ([concatenateAll happy_var_2]
+	)}
+
+happyReduce_96 = happySpecReduce_2  18# happyReduction_96
+happyReduction_96 happy_x_2
+	happy_x_1
+	 =  case happyOut22 happy_x_1 of { happy_var_1 -> 
+	case happyOutTok happy_x_2 of { (TString happy_var_2) -> 
+	happyIn22
+		 (if happy_var_2=="" then happy_var_1 else happy_var_1++[Astring happy_var_2]
+	)}}
+
+happyReduce_97 = happyReduce 4# 18# happyReduction_97
+happyReduction_97 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut22 happy_x_1 of { happy_var_1 -> 
+	case happyOut9 happy_x_3 of { happy_var_3 -> 
+	happyIn22
+		 (happy_var_1++[concatenateAll happy_var_3]
+	) `HappyStk` happyRest}}
+
+happyReduce_98 = happySpecReduce_3  19# happyReduction_98
+happyReduction_98 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
+	case happyOut21 happy_x_3 of { happy_var_3 -> 
+	happyIn23
+		 ([Ast "pair" [Astring happy_var_1,happy_var_3]]
+	)}}
+
+happyReduce_99 = happyReduce 4# 19# happyReduction_99
+happyReduction_99 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut23 happy_x_1 of { happy_var_1 -> 
+	case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
+	case happyOut21 happy_x_4 of { happy_var_4 -> 
+	happyIn23
+		 (happy_var_1++[Ast "pair" [Astring happy_var_2,happy_var_4]]
+	) `HappyStk` happyRest}}}
+
+happyReduce_100 = happySpecReduce_1  20# happyReduction_100
+happyReduction_100 happy_x_1
+	 =  case happyOut27 happy_x_1 of { happy_var_1 -> 
+	happyIn24
+		 (Ast "step" (happy_var_1 "child_step" (Avar "."))
+	)}
+
+happyReduce_101 = happySpecReduce_2  20# happyReduction_101
+happyReduction_101 happy_x_2
+	happy_x_1
+	 =  case happyOut27 happy_x_2 of { happy_var_2 -> 
+	happyIn24
+		 (Ast "step" (happy_var_2 "attribute_step" (Avar "."))
+	)}
+
+happyReduce_102 = happySpecReduce_2  20# happyReduction_102
+happyReduction_102 happy_x_2
+	happy_x_1
+	 =  case happyOut27 happy_x_1 of { happy_var_1 -> 
+	case happyOut25 happy_x_2 of { happy_var_2 -> 
+	happyIn24
+		 (Ast "step" [happy_var_2 (Ast "step" (happy_var_1 "child_step" (Avar ".")))]
+	)}}
+
+happyReduce_103 = happySpecReduce_3  20# happyReduction_103
+happyReduction_103 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut27 happy_x_2 of { happy_var_2 -> 
+	case happyOut25 happy_x_3 of { happy_var_3 -> 
+	happyIn24
+		 (Ast "step" (map happy_var_3 (happy_var_2 "attribute_step" (Avar ".")))
+	)}}
+
+happyReduce_104 = happySpecReduce_1  21# happyReduction_104
+happyReduction_104 happy_x_1
+	 =  case happyOut26 happy_x_1 of { happy_var_1 -> 
+	happyIn25
+		 (happy_var_1
+	)}
+
+happyReduce_105 = happySpecReduce_2  21# happyReduction_105
+happyReduction_105 happy_x_2
+	happy_x_1
+	 =  case happyOut25 happy_x_1 of { happy_var_1 -> 
+	case happyOut26 happy_x_2 of { happy_var_2 -> 
+	happyIn25
+		 (happy_var_2 . happy_var_1
+	)}}
+
+happyReduce_106 = happySpecReduce_2  22# happyReduction_106
+happyReduction_106 happy_x_2
+	happy_x_1
+	 =  case happyOut27 happy_x_2 of { happy_var_2 -> 
+	happyIn26
+		 (\e -> Ast "step" (happy_var_2 "child_step" e)
+	)}
+
+happyReduce_107 = happySpecReduce_3  22# happyReduction_107
+happyReduction_107 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut27 happy_x_3 of { happy_var_3 -> 
+	happyIn26
+		 (\e -> Ast "step" (happy_var_3 "attribute_step" e)
+	)}
+
+happyReduce_108 = happySpecReduce_3  22# happyReduction_108
+happyReduction_108 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut27 happy_x_3 of { happy_var_3 -> 
+	happyIn26
+		 (\e -> Ast "step" (happy_var_3 "descendant_step" e)
+	)}
+
+happyReduce_109 = happyReduce 4# 22# happyReduction_109
+happyReduction_109 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut27 happy_x_4 of { happy_var_4 -> 
+	happyIn26
+		 (\e -> Ast "step" (happy_var_4 "attribute_descendant_step" e)
+	) `HappyStk` happyRest}
+
+happyReduce_110 = happySpecReduce_2  22# happyReduction_110
+happyReduction_110 happy_x_2
+	happy_x_1
+	 =  happyIn26
+		 (\e -> Ast "step" [Ast "parent_step" [e]]
+	)
+
+happyReduce_111 = happySpecReduce_1  23# happyReduction_111
+happyReduction_111 happy_x_1
+	 =  case happyOut28 happy_x_1 of { happy_var_1 -> 
+	happyIn27
+		 (\t e -> [happy_var_1 t e]
+	)}
+
+happyReduce_112 = happyReduce 4# 23# happyReduction_112
+happyReduction_112 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut27 happy_x_1 of { happy_var_1 -> 
+	case happyOut8 happy_x_3 of { happy_var_3 -> 
+	happyIn27
+		 (\t e -> (happy_var_1 t e)++[happy_var_3]
+	) `HappyStk` happyRest}}
+
+happyReduce_113 = happySpecReduce_1  24# happyReduction_113
+happyReduction_113 happy_x_1
+	 =  case happyOut29 happy_x_1 of { happy_var_1 -> 
+	happyIn28
+		 (\t e -> happy_var_1 t e
+	)}
+
+happyReduce_114 = happySpecReduce_1  24# happyReduction_114
+happyReduction_114 happy_x_1
+	 =  happyIn28
+		 (\t e -> Ast t [Astring "*",e]
+	)
+
+happyReduce_115 = happySpecReduce_1  24# happyReduction_115
+happyReduction_115 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
+	happyIn28
+		 (\t e -> Ast t [Astring happy_var_1,e]
+	)}
+
+happyReduce_116 = happySpecReduce_1  25# happyReduction_116
+happyReduction_116 happy_x_1
+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
+	happyIn29
+		 (\_ _ -> happy_var_1
+	)}
+
+happyReduce_117 = happySpecReduce_1  25# happyReduction_117
+happyReduction_117 happy_x_1
+	 =  happyIn29
+		 (\_ e -> e
+	)
+
+happyReduce_118 = happySpecReduce_3  25# happyReduction_118
+happyReduction_118 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut9 happy_x_2 of { happy_var_2 -> 
+	happyIn29
+		 (\t e -> if e == Avar "."
+                                                                     then concatenateAll happy_var_2
+	                                                          else Ast "context" [e,Astring t,concatenateAll happy_var_2]
+	)}
+
+happyReduce_119 = happySpecReduce_2  25# happyReduction_119
+happyReduction_119 happy_x_2
+	happy_x_1
+	 =  happyIn29
+		 (\_ _ -> call "empty" []
+	)
+
+happyReduce_120 = happyReduce 4# 25# happyReduction_120
+happyReduction_120 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
+	case happyOut9 happy_x_3 of { happy_var_3 -> 
+	happyIn29
+		 (\t e -> if e == Avar "."
+                                                                     then call happy_var_1 happy_var_3
+                                                                  else Ast "context" [e,Astring t,call happy_var_1 happy_var_3]
+	) `HappyStk` happyRest}}
+
+happyReduce_121 = happySpecReduce_3  25# happyReduction_121
+happyReduction_121 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
+	happyIn29
+		 (\_ e -> call happy_var_1 (if e == Avar "." then [] else [e])
+	)}
+
+happyNewToken action sts stk [] =
+	happyDoAction 71# notHappyAtAll action sts stk []
+
+happyNewToken action sts stk (tk:tks) =
+	let cont i = happyDoAction i tk action sts stk tks in
+	case tk of {
+	RETURN -> cont 1#;
+	SOME -> cont 2#;
+	EVERY -> cont 3#;
+	IF -> cont 4#;
+	THEN -> cont 5#;
+	ELSE -> cont 6#;
+	LB -> cont 7#;
+	RB -> cont 8#;
+	LP -> cont 9#;
+	RP -> cont 10#;
+	LSB -> cont 11#;
+	RSB -> cont 12#;
+	TO -> cont 13#;
+	PLUS -> cont 14#;
+	MINUS -> cont 15#;
+	TIMES -> cont 16#;
+	DIV -> cont 17#;
+	IDIV -> cont 18#;
+	MOD -> cont 19#;
+	TEQ -> cont 20#;
+	TNE -> cont 21#;
+	TLT -> cont 22#;
+	TLE -> cont 23#;
+	TGT -> cont 24#;
+	TGE -> cont 25#;
+	PRE -> cont 26#;
+	POST -> cont 27#;
+	IS -> cont 28#;
+	SEQ -> cont 29#;
+	SNE -> cont 30#;
+	SLT -> cont 31#;
+	SLE -> cont 32#;
+	SGT -> cont 33#;
+	SGE -> cont 34#;
+	AND -> cont 35#;
+	OR -> cont 36#;
+	NOT -> cont 37#;
+	UNION -> cont 38#;
+	INTERSECT -> cont 39#;
+	EXCEPT -> cont 40#;
+	FOR -> cont 41#;
+	LET -> cont 42#;
+	IN -> cont 43#;
+	COMMA -> cont 44#;
+	ASSIGN -> cont 45#;
+	WHERE -> cont 46#;
+	ORDER -> cont 47#;
+	BY -> cont 48#;
+	ASCENDING -> cont 49#;
+	DESCENDING -> cont 50#;
+	ELEMENT -> cont 51#;
+	ATTRIBUTE -> cont 52#;
+	STAG -> cont 53#;
+	ETAG -> cont 54#;
+	SATISFIES -> cont 55#;
+	ATSIGN -> cont 56#;
+	SLASH -> cont 57#;
+	QName happy_dollar_dollar -> cont 58#;
+	DECLARE -> cont 59#;
+	FUNCTION -> cont 60#;
+	VARIABLE -> cont 61#;
+	AT -> cont 62#;
+	DOTS -> cont 63#;
+	DOT -> cont 64#;
+	SEMI -> cont 65#;
+	Variable happy_dollar_dollar -> cont 66#;
+	XMLtext happy_dollar_dollar -> cont 67#;
+	TInteger happy_dollar_dollar -> cont 68#;
+	TFloat happy_dollar_dollar -> cont 69#;
+	TString happy_dollar_dollar -> cont 70#;
+	_ -> happyError' (tk:tks)
+	}
+
+happyError_ tk tks = happyError' (tk:tks)
+
+newtype HappyIdentity a = HappyIdentity a
+happyIdentity = HappyIdentity
+happyRunIdentity (HappyIdentity a) = a
+
+instance Monad HappyIdentity where
+    return = HappyIdentity
+    (HappyIdentity p) >>= q = q p
+
+happyThen :: () => HappyIdentity a -> (a -> HappyIdentity b) -> HappyIdentity b
+happyThen = (>>=)
+happyReturn :: () => a -> HappyIdentity a
+happyReturn = (return)
+happyThen1 m k tks = (>>=) m (\a -> k a tks)
+happyReturn1 :: () => a -> b -> HappyIdentity a
+happyReturn1 = \a tks -> (return) a
+happyError' :: () => [Token] -> HappyIdentity a
+happyError' = HappyIdentity . parseError
+
+parse tks = happyRunIdentity happySomeParser where
+  happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))
+
+happySeq = happyDontSeq
+
+
+-- Abstract Syntax Tree for XQueries
+data Ast = Ast String [Ast]
+         | Avar String
+         | Aint Int
+         | Afloat Float
+         | Astring String
+         deriving Eq
+
+
+instance Show Ast
+  where show (Ast s []) = s ++ "()"
+        show (Ast s (x:xs)) = s ++ "(" ++ show x
+                              ++ foldr (\a r -> ","++show a++r) "" xs
+                              ++ ")"
+        show (Avar s) = s
+        show (Aint n) = show n
+        show (Afloat n) = show n
+        show (Astring s) = "\'" ++ s ++ "\'"
+
+
+screenSize = 80::Int
+
+prettyAst :: Ast -> Int -> (String,Int)
+prettyAst (Avar s) p = (s,(length s)+p)
+prettyAst (Aint n) p = let s = show n in (s,(length s)+p)
+prettyAst (Afloat n) p = let s = show n in (s,(length s)+p)
+prettyAst (Astring s) p = ("\'" ++ s ++ "\'",(length s)+p+2)
+prettyAst (Ast s args) p
+    = let (ps,np) = prettyArgs args
+      in (s++"("++ps++")",np+1)
+    where prettyArgs [] = ("",p+1)
+          prettyArgs xs = let ss = show (head xs) ++ foldr (\a r -> ","++show a++r) "" (tail xs)
+                              np = (length s)+p+1
+                          in if (length ss)+p < screenSize
+                             then (ss,(length ss)+p)
+                             else let ds = map (\x -> let (s,ep) = prettyAst x np
+                                                      in (s ++ ",\n" ++ space np,ep)) (init xs)
+                                      (ls,lp) = prettyAst (last xs) np
+                                  in (concatMap fst ds ++ ls,lp)
+          space n = replicate n ' '
+
+
+ppAst :: Ast -> String
+ppAst e = let (s,_) = prettyAst e 0 in s
+
+
+call :: String -> [Ast] -> Ast
+call name args = Ast "call" ((Avar name):args)
+
+
+concatenateAll :: [Ast] -> Ast
+concatenateAll [x] = x
+concatenateAll (x:xs) = foldl (\a r -> call "concatenate" [a,r]) x xs
+concatenateAll _ = call "empty" []
+
+
+data Token
+  = RETURN | SOME | EVERY | IF | THEN | ELSE | LB | RB | LP | RP | LSB | RSB
+  | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD
+  | TEQ | TNE | TLT | TLE | TGT | TGE | SEQ | SNE | SLT | SLE | SGT | SGE
+  | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA
+  | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT
+  | ATTRIBUTE | STAG | ETAG | SATISFIES | ATSIGN | SLASH | DECLARE | SEMI
+  | FUNCTION | VARIABLE |AT | DOT | DOTS | TokenEOF | PRE | POST | IS
+  | QName String | Variable String | XMLtext String | TInteger Int
+  | TFloat Float | TString String | TError String
+    deriving Eq
+
+
+instance Show Token
+    where show (QName s) = "QName("++s++")"
+	  show (Variable s) = "Variable("++s++")"
+	  show (XMLtext s) = "XMLtext("++s++")"
+	  show (TInteger n) = "Integer("++(show n)++")"
+	  show (TFloat n) = "Double("++(show n)++")"
+	  show (TString s) = "String("++s++")"
+	  show (TError s) = "'"++s++"'"
+          show t = case filter (\(n,_) -> n==t) tokenList of
+                     (_,b):_ -> b
+                     _ -> "Illegal token"
+
+
+tokenList :: [(Token,String)]
+tokenList = [(RETURN,"return"),(SOME,"some"),(EVERY,"every"),(IF,"if"),(THEN,"then"),(ELSE,"else"),
+             (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"),
+             (TO,"to"),(PLUS,"+"),(MINUS,"-"),(TIMES,"*"),(DIV,"div"),(IDIV,"idiv"),(MOD,"mod"),
+             (TEQ,"="),(TNE,"!="),(TLT,"<"),(TLE,"<="),(TGT,">"),(TGE,">="),(PRE,"<<"),(POST,">>"),
+             (IS,"is"),(SEQ,"eq"),(SNE,"ne"),(SLT,"lt"),(SLE,"le"),(SGT,"gt"),(SGE,"ge"),(AND,"and"),
+             (OR,"or"),(NOT,"not"),(UNION,"union"),(INTERSECT,"intersect"),(EXCEPT,"except"),
+             (FOR,"for"),(LET,"let"),(IN,"in"),(COMMA,"','"),(ASSIGN,":="),(WHERE,"where"),(ORDER,"order"),
+             (BY,"by"),(ASCENDING,"ascending"),(DESCENDING,"descending"),(ELEMENT,"element"),
+             (ATTRIBUTE,"attribute"),(STAG,"</"),(ETAG,"/>"),(SATISFIES,"satisfies"),(ATSIGN,"@"),
+             (SLASH,"/"),(DECLARE,"declare"),(FUNCTION,"function"),(VARIABLE,"variable"),
+             (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";")]
+
+
+parseError tk = error (case tk of
+                         ((TError s):_) -> "Parse error: "++s
+                         _ -> "Parse error: "++(foldr (\a r -> (show a)++" "++r) "" (take 20 tk)))
+
+
+scan :: String -> [Token]
+scan cs = lexer cs ""
+
+
+xmlText :: String -> [Token]
+xmlText "" = []
+xmlText text = [XMLtext text]
+
+
+-- scans XML syntax and returns an XMLtext token with the text
+xml :: String -> String -> String -> [Token]
+xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs ('{':n))
+xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs ('<':'/':n))
+xml ('<':'!':'-':cs) text n = xmlComment cs (text++"<!-") n
+xml ('<':cs) text n = (xmlText text)++(TLT : lexer cs ('<':n))
+xml ('(':':':cs) text n = xqComment cs text n
+xml (c:cs) text n = xml cs (text++[c]) n
+xml [] text _ = xmlText text
+
+
+xqComment :: String -> String -> String -> [Token]
+xqComment (':':')':cs) text n = xml cs text n
+xqComment (_:cs) text n = xqComment cs text n
+xqComment [] text _ = xmlText text
+
+
+xmlComment :: String -> String -> String -> [Token]
+xmlComment ('-':'>':cs) text n = xml cs (text++"->") n
+xmlComment (c:cs) text n = xmlComment cs (text++[c]) n
+xmlComment [] text _ = xmlText text
+
+
+isQN :: Char -> Bool
+isQN c = elem c "_:-" || isDigit c || isAlpha c
+
+
+isVar :: Char -> Bool
+isVar c = elem c "_" || isDigit c || isAlpha c
+
+
+inXML :: String -> Bool
+inXML ('>':'<':_) = True
+inXML _ = False
+
+
+-- the XQuery scanner
+lexer :: String -> String -> [Token]
+lexer [] "" = []
+lexer [] _ = [ TError "Unexpected end of input" ]
+lexer (' ':'>':' ':cs) n = TGT : lexer cs n
+lexer (c:cs) n
+      | isSpace c = lexer cs n
+      | isAlpha c = lexVar (c:cs) n
+      | isDigit c = lexNum (c:cs) n
+lexer ('$':c:cs) n | isAlpha c
+      = let (var,rest) = span isVar (c:cs)
+        in (Variable var) : lexer rest n
+lexer (':':'=':cs) n = ASSIGN : lexer cs n
+lexer ('<':'/':cs) n = STAG : lexer cs ('<':'/':n)
+lexer ('<':'=':cs) n = TLE : lexer cs n
+lexer ('>':'=':cs) n = TGE : lexer cs n
+lexer ('<':'<':cs) n = PRE : lexer cs n
+lexer ('>':'>':cs) n = POST : lexer cs n
+lexer ('/':'>':cs) m = case m of
+                         '<':n -> ETAG : (if inXML n then xml cs "" n else lexer cs n)
+                         _ -> [ TError "Unexpected token: '/>'" ]
+lexer ('(':':':cs) n = lexComment cs n
+lexer ('<':'!':'-':cs) n = lexXmlComment cs "<!-" n
+lexer ('.':'.':cs) n = DOTS : lexer cs n
+lexer ('.':cs) n = DOT : lexer cs n
+lexer ('!':'=':cs) n = TNE : lexer cs n
+lexer ('\'':cs) n = lexString cs "" ('\'':n)
+lexer ('\"':cs) n = lexString cs "" ('\"': n)
+lexer ('[':cs) n = LB : lexer cs n
+lexer (']':cs) n = RB : lexer cs n
+lexer ('(':cs) n = LP : lexer cs n
+lexer (')':cs) n = RP : lexer cs n
+lexer ('}':cs) m = case m of
+                     '{':'\"':n -> RSB : lexString cs "" ('\"':n)
+                     '{':'\'':n -> RSB : lexString cs "" ('\'':n)
+                     '{':n -> RSB : (if inXML n then xml cs "" n else lexer cs n)
+                     _ -> [ TError "Unexpected token: '}'" ]
+lexer ('+':cs) n = PLUS : lexer cs n
+lexer ('-':cs) n = MINUS : lexer cs n
+lexer ('*':cs) n = TIMES : lexer cs n
+lexer ('=':cs) n = TEQ : lexer cs n
+lexer ('<':c:cs) n = TLT : (lexer (c:cs) (if isAlpha c then ('<':n) else n))
+lexer ('>':cs) m = case m of
+                     '<':'/':'>':'<':n -> TGT : (if inXML n then xml cs "" n else lexer cs n)
+                     '<':n -> TGT : xml cs "" ('>':m) 
+                     _ -> TGT : lexer cs m
+lexer (',':cs) n = COMMA : lexer cs n
+lexer ('@':cs) n = ATSIGN : lexer cs n
+lexer ('/':cs) n = SLASH : lexer cs n
+lexer ('{':cs) n = LSB : lexer cs ('{':n)
+lexer ('|':cs) n = UNION : lexer cs n
+lexer (';':cs) n = SEMI : lexer cs n
+lexer (c:cs) n = TError ("Illegal character: '"++[c,'\'']) : lexer cs n
+
+
+lexNum :: String -> String -> [Token]
+lexNum cs n = if null rest || head rest /= '.'
+                 then TInteger (read k) : lexer rest n
+              else let (m,rest2) = span isDigit (tail rest)
+                       val::Float = read (k++('.':m))
+                   in case rest2 of
+                        ('e':rest3) -> let (exp,rest4) = span isDigit rest3
+                                       in (TFloat (val*10^(read exp))) : lexer rest4 n
+                        _ -> (TFloat val) : lexer rest2 n
+      where (k,rest) = span isDigit cs
+
+
+lexString :: String -> String -> String -> [Token]
+lexString ('\"':cs) s m = case m of
+                            '\"':n -> (TString s) : (lexer cs n)
+                            _ -> lexString cs (s++"\"") m
+lexString ('\'':cs) s m = case m of
+                            '\'':n -> (TString s) : (lexer cs n)
+                            _ -> lexString cs (s++"\'") m
+lexString ('{':cs) s n = (TString s) : LSB : (lexer cs ('{':n))
+lexString (c:cs) s n = lexString cs (s++[c]) n
+lexString [] s n = [ TError "End of input while in string" ]
+
+
+lexComment :: String -> String -> [Token]
+lexComment (':':')':cs) n = lexer cs n
+lexComment (_:cs) n = lexComment cs n
+lexComment [] n = [ TError "End of input while in comment" ]
+
+
+lexXmlComment :: String -> String -> String -> [Token]
+lexXmlComment ('-':'>':cs) text n = (xmlText (text++"->"))++(lexer cs n)
+lexXmlComment (c:cs) text n = lexXmlComment cs (text++[c]) n
+lexXmlComment [] text _ = xmlText text
+
+
+lexVar :: String -> String -> [Token]
+lexVar cs n =
+    let (nm,rest) = span isQN cs
+    in (case nm of
+          "return" -> RETURN
+          "some" -> SOME
+          "every" -> EVERY
+          "if" -> IF
+          "then" -> THEN
+          "else" -> ELSE
+          "to" -> TO
+          "div" -> DIV
+          "idiv" -> IDIV
+          "mod" -> MOD
+          "and" -> AND
+          "or" -> OR
+          "not" -> NOT
+          "union" -> UNION
+          "intersect" -> INTERSECT
+          "except" -> EXCEPT
+          "for" -> FOR
+          "let" -> LET
+          "in" -> IN
+          "where" -> WHERE
+          "order" -> ORDER
+          "by" -> BY
+          "ascending" -> ASCENDING
+          "descending" -> DESCENDING
+          "element" -> ELEMENT
+          "attribute" -> ATTRIBUTE
+          "satisfies" -> SATISFIES
+          "declare" -> DECLARE
+          "function" -> FUNCTION
+          "variable" -> VARIABLE
+          "at" -> AT
+          "eq" -> SEQ
+          "ne" -> SNE
+          "lt" -> SLT
+          "le" -> SLE
+          "gt" -> SGT
+          "ge" -> SGE
+          "is" -> IS
+          var -> QName var
+       ) : lexer rest n
+{-# LINE 1 "templates/GenericTemplate.hs" #-}
+{-# LINE 1 "templates/GenericTemplate.hs" #-}
+{-# LINE 1 "<built-in>" #-}
+{-# LINE 1 "<command line>" #-}
+{-# LINE 1 "templates/GenericTemplate.hs" #-}
+-- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp 
+
+{-# LINE 28 "templates/GenericTemplate.hs" #-}
+
+
+data Happy_IntList = HappyCons Int# Happy_IntList
+
+
+
+
+
+{-# LINE 49 "templates/GenericTemplate.hs" #-}
+
+{-# LINE 59 "templates/GenericTemplate.hs" #-}
+
+{-# LINE 68 "templates/GenericTemplate.hs" #-}
+
+infixr 9 `HappyStk`
+data HappyStk a = HappyStk a (HappyStk a)
+
+-----------------------------------------------------------------------------
+-- starting the parse
+
+happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll
+
+-----------------------------------------------------------------------------
+-- Accepting the parse
+
+-- If the current token is 0#, it means we've just accepted a partial
+-- parse (a %partial parser).  We must ignore the saved token on the top of
+-- the stack in this case.
+happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =
+	happyReturn1 ans
+happyAccept j tk st sts (HappyStk ans _) = 
+	(happyTcHack j (happyTcHack st)) (happyReturn1 ans)
+
+-----------------------------------------------------------------------------
+-- Arrays only: do the next action
+
+
+
+happyDoAction i tk st
+	= {- nothing -}
+
+
+	  case action of
+		0#		  -> {- nothing -}
+				     happyFail i tk st
+		-1# 	  -> {- nothing -}
+				     happyAccept i tk st
+		n | (n <# (0# :: Int#)) -> {- nothing -}
+
+				     (happyReduceArr ! rule) i tk st
+				     where rule = (I# ((negateInt# ((n +# (1# :: Int#))))))
+		n		  -> {- nothing -}
+
+
+				     happyShift new_state i tk st
+				     where new_state = (n -# (1# :: Int#))
+   where off    = indexShortOffAddr happyActOffsets st
+	 off_i  = (off +# i)
+	 check  = if (off_i >=# (0# :: Int#))
+			then (indexShortOffAddr happyCheck off_i ==#  i)
+			else False
+ 	 action | check     = indexShortOffAddr happyTable off_i
+		| otherwise = indexShortOffAddr happyDefActions st
+
+{-# LINE 127 "templates/GenericTemplate.hs" #-}
+
+
+indexShortOffAddr (HappyA# arr) off =
+#if __GLASGOW_HASKELL__ > 500
+	narrow16Int# i
+#elif __GLASGOW_HASKELL__ == 500
+	intToInt16# i
+#else
+	(i `iShiftL#` 16#) `iShiftRA#` 16#
+#endif
+  where
+#if __GLASGOW_HASKELL__ >= 503
+	i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)
+#else
+	i = word2Int# ((high `shiftL#` 8#) `or#` low)
+#endif
+	high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
+	low  = int2Word# (ord# (indexCharOffAddr# arr off'))
+	off' = off *# 2#
+
+
+
+
+
+data HappyAddr = HappyA# Addr#
+
+
+
+
+-----------------------------------------------------------------------------
+-- HappyState data type (not arrays)
+
+{-# LINE 170 "templates/GenericTemplate.hs" #-}
+
+-----------------------------------------------------------------------------
+-- Shifting a token
+
+happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =
+     let i = (case unsafeCoerce# x of { (I# (i)) -> i }) in
+--     trace "shifting the error token" $
+     happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)
+
+happyShift new_state i tk st sts stk =
+     happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)
+
+-- happyReduce is specialised for the common cases.
+
+happySpecReduce_0 i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happySpecReduce_0 nt fn j tk st@((action)) sts stk
+     = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)
+
+happySpecReduce_1 i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')
+     = let r = fn v1 in
+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
+
+happySpecReduce_2 i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')
+     = let r = fn v1 v2 in
+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
+
+happySpecReduce_3 i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')
+     = let r = fn v1 v2 v3 in
+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
+
+happyReduce k i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happyReduce k nt fn j tk st sts stk
+     = case happyDrop (k -# (1# :: Int#)) sts of
+	 sts1@((HappyCons (st1@(action)) (_))) ->
+        	let r = fn stk in  -- it doesn't hurt to always seq here...
+       		happyDoSeq r (happyGoto nt j tk st1 sts1 r)
+
+happyMonadReduce k nt fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happyMonadReduce k nt fn j tk st sts stk =
+        happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))
+       where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts))
+             drop_stk = happyDropStk k stk
+
+happyMonad2Reduce k nt fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happyMonad2Reduce k nt fn j tk st sts stk =
+       happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))
+       where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts))
+             drop_stk = happyDropStk k stk
+
+             off    = indexShortOffAddr happyGotoOffsets st1
+             off_i  = (off +# nt)
+             new_state = indexShortOffAddr happyTable off_i
+
+
+
+
+happyDrop 0# l = l
+happyDrop n (HappyCons (_) (t)) = happyDrop (n -# (1# :: Int#)) t
+
+happyDropStk 0# l = l
+happyDropStk n (x `HappyStk` xs) = happyDropStk (n -# (1#::Int#)) xs
+
+-----------------------------------------------------------------------------
+-- Moving to a new state after a reduction
+
+
+happyGoto nt j tk st = 
+   {- nothing -}
+   happyDoAction j tk new_state
+   where off    = indexShortOffAddr happyGotoOffsets st
+	 off_i  = (off +# nt)
+ 	 new_state = indexShortOffAddr happyTable off_i
+
+
+
+
+-----------------------------------------------------------------------------
+-- Error recovery (0# is the error token)
+
+-- parse error if we are in recovery and we fail again
+happyFail  0# tk old_st _ stk =
+--	trace "failing" $ 
+    	happyError_ tk
+
+{-  We don't need state discarding for our restricted implementation of
+    "error".  In fact, it can cause some bogus parses, so I've disabled it
+    for now --SDM
+
+-- discard a state
+happyFail  0# tk old_st (HappyCons ((action)) (sts)) 
+						(saved_tok `HappyStk` _ `HappyStk` stk) =
+--	trace ("discarding state, depth " ++ show (length stk))  $
+	happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))
+-}
+
+-- Enter error recovery: generate an error token,
+--                       save the old token and carry on.
+happyFail  i tk (action) sts stk =
+--      trace "entering error recovery" $
+	happyDoAction 0# tk action sts ( (unsafeCoerce# (I# (i))) `HappyStk` stk)
+
+-- Internal happy errors:
+
+notHappyAtAll = error "Internal Happy error\n"
+
+-----------------------------------------------------------------------------
+-- Hack to get the typechecker to accept our action functions
+
+
+happyTcHack :: Int# -> a -> a
+happyTcHack x y = y
+{-# INLINE happyTcHack #-}
+
+
+-----------------------------------------------------------------------------
+-- Seq-ing.  If the --strict flag is given, then Happy emits 
+--	happySeq = happyDoSeq
+-- otherwise it emits
+-- 	happySeq = happyDontSeq
+
+happyDoSeq, happyDontSeq :: a -> b -> b
+happyDoSeq   a b = a `seq` b
+happyDontSeq a b = b
+
+-----------------------------------------------------------------------------
+-- Don't inline any functions from the template.  GHC has a nasty habit
+-- of deciding to inline happyGoto everywhere, which increases the size of
+-- the generated parser quite a bit.
+
+
+{-# NOINLINE happyDoAction #-}
+{-# NOINLINE happyTable #-}
+{-# NOINLINE happyCheck #-}
+{-# NOINLINE happyActOffsets #-}
+{-# NOINLINE happyGotoOffsets #-}
+{-# NOINLINE happyDefActions #-}
+
+{-# NOINLINE happyShift #-}
+{-# NOINLINE happySpecReduce_0 #-}
+{-# NOINLINE happySpecReduce_1 #-}
+{-# NOINLINE happySpecReduce_2 #-}
+{-# NOINLINE happySpecReduce_3 #-}
+{-# NOINLINE happyReduce #-}
+{-# NOINLINE happyMonadReduce #-}
+{-# NOINLINE happyGoto #-}
+{-# NOINLINE happyFail #-}
+
+-- end of Happy Template.
diff --git a/Text/XML/HXQ/XQuery.hs b/Text/XML/HXQ/XQuery.hs
new file mode 100644
--- /dev/null
+++ b/Text/XML/HXQ/XQuery.hs
@@ -0,0 +1,43 @@
+{-------------------------------------------------------------------------------------
+-
+- The XQuery Compiler and Interpreter
+- Programmer: Leonidas Fegaras
+- Email: fegaras@cse.uta.edu
+- Web: http://lambda.uta.edu/
+- Creation: 03/22/08, last update: 07/24/08
+- 
+- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
+- This material is provided as is, with absolutely no warranty expressed or implied.
+- Any use is at your own risk. Permission is hereby granted to use or copy this program
+- for any purpose, provided the above notices are retained on all copies.
+-
+--------------------------------------------------------------------------------------}
+
+
+-- | HXQ is a fast and space-efficient compiler from XQuery (the standard
+-- query language for XML) to embedded Haskell code. The translation is
+-- based on Haskell templates. It also provides an interpreter for
+-- evaluating ad-hoc XQueries read from input or from files and database connectivity using HDBC.
+-- For more information, look at <http://lambda.uta.edu/HXQ/>.
+module Text.XML.HXQ.XQuery (
+       -- * The XML Data Representation
+       XTree(..), XSeq, Tag, AttList, putXSeq,
+       -- * The XQuery Compiler
+       xq, xe,
+       -- * The XQuery Interpreter
+       xquery, xfile,
+       -- * The XQuery Compiler with Database Connectivity
+       xqdb, connect, disconnect, prepareSQL, executeSQL,
+       -- * The XQuery Interpreter with Database Connectivity
+       xqueryDB, xfileDB,
+       -- * Shredding and Publishing XML Documents Using a Relational Database
+       shred, createIndex
+    ) where
+
+import HXML(AttList)
+import Text.XML.HXQ.XTree
+import Text.XML.HXQ.Compiler
+import Text.XML.HXQ.Interpreter
+import Text.XML.HXQ.DB
+import Text.XML.HXQ.DBConnect
+import Database.HDBC(disconnect)
diff --git a/Text/XML/HXQ/XTree.hs b/Text/XML/HXQ/XTree.hs
new file mode 100644
--- /dev/null
+++ b/Text/XML/HXQ/XTree.hs
@@ -0,0 +1,147 @@
+{-------------------------------------------------------------------------------------
+-
+- XML Trees (represented as rose trees)
+- Programmer: Leonidas Fegaras
+- Email: fegaras@cse.uta.edu
+- Web: http://lambda.uta.edu/
+- Creation: 05/01/08, last update: 07/24/08
+- 
+- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
+- This material is provided as is, with absolutely no warranty expressed or implied.
+- Any use is at your own risk. Permission is hereby granted to use or copy this program
+- for any purpose, provided the above notices are retained on all copies.
+-
+--------------------------------------------------------------------------------------}
+
+
+{-# OPTIONS_GHC -funbox-strict-fields #-}
+
+
+module Text.XML.HXQ.XTree where
+
+import System.IO
+import XMLParse(XMLEvent(..))
+import HXML(AttList)
+import Text.XML.HXQ.Parser(Ast(..))
+import Database.HDBC(Statement)
+
+
+instance Eq Statement where x == y = False
+
+
+type Tag = String
+
+
+-- | Rose tree representation of XML data.
+-- The Int in XElem is the preorder numbering used for the document order of nodes.
+data XTree =  XElem    !Tag !AttList !Int XTree [XTree]   -- ^ an XML tree node (element)
+           |  XText    !String          -- ^ an XML tree leaf (PCDATA)
+           |  XInt     !Int             -- ^ an XML tree leaf (int)
+           |  XFloat   !Float           -- ^ an XML tree leaf (float)
+           |  XBool    !Bool            -- ^ an XML tree leaf (boolean)
+           |  XPI      Tag String	-- ^ processing instruction
+           |  XGERef   Tag		-- ^ general entity reference
+           |  XComment String		-- ^ comment
+           |  XError   String		-- ^ error report
+           |  XStmt    Statement        -- ^ used internally to wrap an SQL statement
+           |  XNoPad                    -- ^ marker for no padding in XSeq
+           deriving Eq
+
+
+type XSeq = [XTree]
+
+
+showAL :: AttList -> String
+showAL = foldr (\(a,v) r -> " "++a++"=\""++v++"\""++r) []
+
+showXT :: XTree -> Bool -> String
+showXT e pad
+    = case e of
+        XElem tag al _ _ [] -> "<"++tag++showAL al++"/>"
+        XElem tag al _ _ xs -> "<"++tag++showAL al++">"++showXS xs++"</"++tag++">"
+        XText text -> p++text
+        XInt n -> p++show n
+        XFloat n -> p++show n
+        XBool v -> p++if v then "true" else "false"
+        XComment s -> "<!--"++s++"-->"
+        XPI n s -> "<?"++n++" "++s++">"
+        XError s -> error s
+        _ -> ""
+      where p = if pad then " " else ""
+
+showXS :: XSeq -> String
+showXS [] = ""
+showXS (x:xs) = showXT x False ++ sXS xs
+    where sXS (XNoPad:x:xs) = (showXT x False) ++ sXS xs
+          sXS (x:xs) = (showXT x True) ++ sXS xs
+          sXS _ = ""
+
+instance Show XTree where
+    show t = showXT t False
+
+
+-- | Print the XQuery result (which is a sequence of XML fragments) without buffering.
+putXSeq :: XSeq -> IO ()
+putXSeq xs = hSetBuffering stdout NoBuffering >> putStrLn (showXS xs)
+
+
+
+{--------------- Build the rose tree from the XML stream ----------------------------}
+
+
+type Stream = [XMLEvent]
+
+noParentError = error "parent references are not supported yet"
+
+-- lazily materialize the SAX stream into a DOM tree
+materializeWithoutParent :: Stream -> XTree
+materializeWithoutParent stream
+    = XElem "document" [] 1 noParentError
+            [head (filter (\x -> case x of XElem _ _ _ _ _ -> True; _ -> False)
+                          ((\(x,_,_)->x) (ml stream 2)))]
+      where m ((TextEvent t):xs) i = (XText t,xs,i)
+            m ((EmptyEvent n atts):xs) i = (XElem n atts i noParentError [],xs,i+1)
+            m ((StartEvent n atts):xs) i
+                = let (el,xs',i') = ml xs (i+1)
+                  in (XElem n atts i noParentError el,xs',i')
+            m ((PIEvent n s):xs) i = (XPI n s,xs,i)
+            m ((CommentEvent s):xs) i = (XComment s,xs,i)
+            m ((GERefEvent n):xs) i = (XGERef n,xs,i)
+            m ((ErrorEvent s):xs) i = (XError s,xs,i)
+            m (_:xs) i = (XError "unrecognized XML event",xs,i)
+            m [] i = (XError "unbalanced tags",[],i)
+            ml [] i = ([],[],i)
+            ml ((EndEvent n):xs) i = ([],xs,i)
+            ml xs i = let (e,xs',i') = m xs i
+                          (el,xs'',i'') = ml xs' i'
+                      in (e:el,xs'',i'')
+
+
+-- lazily materialize the SAX stream into a DOM tree that contains parent references
+-- Not used because it has space leaks for large documents
+materializeWithParent :: Stream -> XTree
+materializeWithParent stream = root
+    where root = XElem "document" [] 1 (error "Trying to access the root parent")
+                       [head (filter (\x -> case x of XElem _ _ _ _ _ -> True; _ -> False)
+                                     ((\(x,_,_)->x) (ml stream 2 root)))]
+          m ((TextEvent t):xs) i _ = (XText t,xs,i)
+          m ((EmptyEvent n atts):xs) i p = (XElem n atts i p [],xs,i+1)
+          m ((StartEvent n atts):xs) i p
+              = let (el,xs',i') = ml xs (i+1) node
+                    node = XElem n atts i p el
+                in (node,xs',i')
+          m ((PIEvent n s):xs) i _ = (XPI n s,xs,i)
+          m ((CommentEvent s):xs) i _ = (XComment s,xs,i)
+          m ((GERefEvent n):xs) i _ = (XGERef n,xs,i)
+          m ((ErrorEvent s):xs) i _ = (XError s,xs,i)
+          m (_:xs) i _ = (XError "unrecognized XML event",xs,i)
+          m [] i _ = (XError "unbalanced tags",[],i)
+          ml [] i _ = ([],[],i)
+          ml ((EndEvent n):xs) i _ = ([],xs,i)
+          ml xs i p = let (e,xs',i') = m xs i p
+                          (el,xs'',i'') = ml xs' i' p
+                      in (e:el,xs'',i'')
+
+
+materialize :: Stream -> XTree
+materialize = materializeWithoutParent
diff --git a/XML/HXQ/Compiler.hs b/XML/HXQ/Compiler.hs
deleted file mode 100644
--- a/XML/HXQ/Compiler.hs
+++ /dev/null
@@ -1,836 +0,0 @@
-{-------------------------------------------------------------------------------------
--
-- A Compiler from XQuery to Haskell
-- Programmer: Leonidas Fegaras
-- Email: fegaras@cse.uta.edu
-- Web: http://lambda.uta.edu/
-- Creation: 02/15/08, last update: 06/21/08
-- 
-- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
-- This material is provided as is, with absolutely no warranty expressed or implied.
-- Any use is at your own risk. Permission is hereby granted to use or copy this program
-- for any purpose, provided the above notices are retained on all copies.
--
---------------------------------------------------------------------------------------}
-
-
-{-# OPTIONS_GHC -fth -fbang-patterns #-}
-
-module XML.HXQ.Compiler where
-
-import Data.List
-import Control.Monad
-import Char(isDigit,toLower)
-import List(sortBy)
-import Language.Haskell.TH
-import Database.HDBC
-import XMLParse(parseDocument)
-import HXML(AttList)
-import XML.HXQ.Parser
-import XML.HXQ.XTree
-import XML.HXQ.Optimizer
-import XML.HXQ.DB
-import XML.HXQ.DBConnect
-
-
-{--------------- XPath Steps ---------------------------------------------------------}
-
-
-current_step :: Tag -> XTree -> XSeq
-current_step m x
-    = case x of
-        XElem k _ _ _ _ | (k==m || m=="*") -> [x]
-        _ -> []
-
-
--- XPath step /tag or /*
-child_step :: Tag -> XTree -> XSeq
-child_step m x
-    = case x of
-        XElem _ _ _ _ bs
-            -> foldr (\b s -> case b of
-                                XElem k _ _ _ _ | (k==m || m=="*") -> b:s
-                                _ -> s) [] bs
-        _ -> []
-
-
--- XPath step //tag or //*
-descendant_step :: Tag -> XTree -> XSeq
-descendant_step m (x@(XElem t _ _ _ cs))
-    | m==t || m=="*"
-    = x:(concatMap (descendant_step m) cs)
-descendant_step m (XElem t _ _ _ cs) = concatMap (descendant_step m) cs
-descendant_step m _ = []
-
-
--- It's like //* but has tagged children, which are derived statically
--- After examing 100 children it gives up: this avoids space leaks
-descendant_any_with_tagged_children :: [Tag] -> XTree -> XSeq
-descendant_any_with_tagged_children tags (x@(XElem t _ _ _ cs))
-    | all (\tag -> foldr (\b s -> case b of
-                                    (XElem k _ _ _ _) -> s || k == tag
-                                    _ -> s) False cs100) tags
-    = x:(concatMap (descendant_any_with_tagged_children tags) cs)
-    where cs100 = take 100 cs
-descendant_any_with_tagged_children tags (XElem t _ _ _ cs)
-    = concatMap (descendant_any_with_tagged_children tags) cs
-descendant_any_with_tagged_children tags _ = []
-
-
--- XPath step /@attr or /@*
-attribute_step :: Tag -> XTree -> XSeq
-attribute_step m x
-    = case x of
-        (XElem _ al _ _ _) -> foldr (\(k,v) s -> if k==m || m=="*"
-                                                 then (XText v):s
-                                                 else s) [] al
-        _ -> []
-
-
--- XPath step //@attr or //@*
-attribute_descendant_step :: Tag -> XTree -> XSeq
-attribute_descendant_step m (x@(XElem _ al _ _ cs))
-    = foldr (\(k,v) s -> if k==m || m=="*"
-                         then (XText v):s
-                         else s)
-            (concatMap (attribute_descendant_step m) cs) al
-attribute_descendant_step m _ = []
-
-
--- NOT USED: XPath step /..
-parent_step :: Tag -> XTree -> XSeq
-parent_step _ (XElem _ _ _ p _) = [p]
-parent_step _ e = error ("Cannot derive the parent of "++show e)
-
-
-{------------ Functions --------------------------------------------------------------}
-
-
--- find the value of a variable in an association list
-findV var env
-  = case filter (\(n,_) -> n==var) env of
-      (_,b):_ -> b
-      _ -> error ("Undefined variable: "++var)
-
--- is the variable defined in the association list?
-memV var env
-  = case filter (\(n,_) -> n==var) env of
-      (_,b):_ -> True
-      _ -> False
-
-
--- like foldr but with an index
-foldir :: (a -> Int -> b -> b) -> b -> [a] -> Int -> b
-foldir c n [] i = n
-foldir c n (x:xs) i = c x i (foldir c n xs (i+1))
-
-
-trueXT = XBool True
-falseXT = XBool False
-
-
-readNum :: String -> Maybe XTree
-readNum cs = case span isDigit cs of
-               (n,[]) -> Just (XInt (read n))
-               (n,'.':rest) -> case span isDigit rest of
-                                 (k,[]) -> Just (XFloat (read (n++('.':k))))
-                                 _ -> Nothing
-               _ -> Nothing
-
-
-text :: XSeq -> XSeq
-text xs = foldr (\x r -> case x of
-                           XElem _ _ _ _ zs
-                               -> (filter (\a -> case a of XText _ -> True; XInt _ -> True;
-                                                           XFloat _ -> True; XBool _ -> True; _ -> False) zs)++r
-                           XText _ -> x:r
-                           XInt _ -> x:r
-                           XFloat _ -> x:r
-                           XBool _ -> x:r
-                           _ -> r) [] xs
-
-
-toString :: XSeq -> [String]
-toString xs = map (\x -> case x of 
-                           XText t -> t
-                           XInt n -> show n
-                           XFloat n -> show n
-                           XBool n -> show n)
-                  (text xs)
-
-
--- concatenate text with no padding (for element content)
-appendText :: [XSeq] -> XSeq
-appendText [] = []
-appendText [x] = x
-appendText (x:xs) = x++[XNoPad]++appendText xs
-
-
-toNum :: XSeq -> XSeq
-toNum xs = foldr (\x r -> case x of
-                            XInt n -> x:r
-                            XFloat n -> x:r
-                            XText s -> case readNum s of
-                                         Just t -> t:r
-                                         _ -> r
-                            _ -> r) [] (text xs)
-
-
-toFloat :: XTree -> Float
-toFloat (XText s) = case readNum s of
-                      Just (XInt n) -> fromIntegral n
-                      Just (XFloat n) -> n
-                      _ -> error("Cannot convert to a float: "++s)
-toFloat (XInt n) = fromIntegral n
-toFloat (XFloat n) = n
-toFloat x = error("Cannot convert to a float: "++(show x))
-
-
-mean :: (Fractional t) => [t] -> t
-mean = uncurry (/) . foldl' (\(!s, !n) x -> (s+x, n+1)) (0,0.0)
-
-
-contains :: String -> String -> Bool
-contains text word
-    = let len = length word
-          c xs | ((take len xs) == word) = True
-          c (_:xs) = c xs
-          c _ = False
-      in c text
-
-
-distinct :: Eq a => [a] -> [a]
-distinct = foldl (\r a -> if elem a r then r else r++[a]) []
-
-
-arithmetic :: (Float -> Float -> Float) -> XTree -> XTree -> XTree
-arithmetic op (XInt n) (XInt m) = XInt (round (op (fromIntegral n) (fromIntegral m)))
-arithmetic op (XFloat n) (XFloat m) = XFloat (op n m)
-arithmetic op (XFloat n) (XInt m) = XFloat (op n (fromIntegral m))
-arithmetic op (XInt n) (XFloat m) = XFloat (op (fromIntegral n) m)
-
-
-compareXTrees :: XTree -> XTree -> Ordering
-compareXTrees (XElem _ _ _ _ _) _ = EQ
-compareXTrees _ (XElem _ _ _ _ _) = EQ
-compareXTrees (XInt n) (XInt m) = compare n m
-compareXTrees (XFloat n) (XInt m) = compare n (fromIntegral m)
-compareXTrees (XInt n) (XFloat m) = compare (fromIntegral n) m
-compareXTrees (XFloat n) (XFloat m) = compare n m
-compareXTrees (XText n) (XText m) = compare n m
-compareXTrees x y = compare (toFloat x) (toFloat y)
-
-
-strictCompareOne [XInt n] [XInt m] = compare n m
-strictCompareOne [XFloat n] [XFloat m] = compare n m
-strictCompareOne [XFloat n] [XInt m] = compare n (fromIntegral m)
-strictCompareOne [XInt n] [XFloat m] = compare (fromIntegral n) m
-strictCompareOne [XText n] [XText m] = compare n m
-strictCompareOne x y = error ("Illegal operands in strict comparison: "++(show x)++" "++(show y))
-
-strictCompare :: XSeq -> XSeq -> Ordering
-strictCompare [XElem _ _ _ _ x] [XElem _ _ _ _ y] = strictCompareOne x y
-strictCompare x [XElem _ _ _ _ y] = strictCompareOne x y
-strictCompare [XElem _ _ _ _ x] y = strictCompareOne x y
-strictCompare x y = strictCompareOne x y
-
-compareXSeqs :: Bool -> XSeq -> XSeq -> Ordering
-compareXSeqs ord xs ys
-    = let comps = [ compareXTrees x y | x <- xs, y <- ys ]
-      in if ord
-            then if all (\x -> x == LT) comps
-                    then LT
-                 else if all (\x -> x == GT) comps
-                    then GT
-                 else EQ
-         else if all (\x -> x == LT) comps
-                 then GT
-              else if all (\x -> x == GT) comps
-                 then LT
-              else EQ
-
-
-conditionTest :: XSeq -> Bool
-conditionTest [] = False
-conditionTest [XText ""] = False
-conditionTest [XInt 0] = False
-conditionTest [XBool False] = False
-conditionTest _ = True
-
-
--- XPath steps
-paths :: [(Tag,Q Exp)]
-paths = [ ( "current_step", [| current_step |] ),
-          ( "child_step", [| child_step |] ),
-          ( "descendant_step", [| descendant_step |] ),
-          ( "attribute_step", [| attribute_step |] ),
-          ( "attribute_descendant_step", [| attribute_descendant_step |] ),
-          ( "parent_step", [| parent_step |] )
-        ]
-
-
-type Function = [Q Exp] -> Q Exp
-
--- System functions: they can also be defined as Haskell functions of type (XSeq,...,XSeq) -> XSeq
--- but here we make sure they are unfolded and fused with the rest of the query
-functions :: [(Tag,Int,Function)]
-functions = [ ( "=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ] |] ),
-              ( "!=", 2, \[xs,ys] -> [| if null [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ]
-                                        then [trueXT]
-                                        else [falseXT] |] ),
-              ( ">", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == GT ] |] ),
-              ( "<", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == LT ] |] ),
-              ( ">=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y `elem` [GT,EQ] ] |] ),
-              ( "<=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y `elem` [LT,EQ] ] |] ),
-              ( "eq", 2, \[xs,ys] -> [| if strictCompare $xs $ys == EQ then [trueXT] else [falseXT] |] ),
-              ( "neq", 2, \[xs,ys] -> [| if strictCompare $xs $ys /= EQ then [trueXT] else [falseXT] |] ),
-              ( "lt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == LT then [trueXT] else [falseXT] |] ),
-              ( "gt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == GT then [trueXT] else [falseXT] |] ),
-              ( "le", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [LT,EQ] then [trueXT] else [falseXT] |] ),
-              ( "ge", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [GT,EQ] then [trueXT] else [falseXT] |] ),
-              ( "<<", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ _ <- $xs, XElem _ _ oy _ _ <- $ys, ox < oy ] |] ),
-              ( ">>", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ _ <- $xs, XElem _ _ oy _ _ <- $ys, ox > oy ] |] ),
-              ( "is", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ _ <- $xs, XElem _ _ oy _ _ <- $ys, ox == oy ] |] ),
-              ( "+", 2, \[xs,ys] -> [| [ arithmetic (+) x y | x <- toNum $xs, y <- toNum $ys ] |] ),
-              ( "-", 2, \[xs,ys] -> [| [ arithmetic (-) x y | x <- toNum $xs, y <- toNum $ys ] |] ),
-              ( "*", 2, \[xs,ys] -> [| [ arithmetic (*) x y | x <- toNum $xs, y <- toNum $ys ] |] ),
-              ( "div", 2, \[xs,ys] -> [| [ arithmetic (/) x y | x <- toNum $xs, y <- toNum $ys ] |] ),
-              ( "idiv", 2, \[xs,ys] -> [| [ XInt (div x y) | (XInt x) <- toNum $xs, (XInt y) <- toNum $ys ] |] ),
-              ( "mod", 2, \[xs,ys] -> [| [ XInt (mod x y) | (XInt x) <- toNum $xs, (XInt y) <- toNum $ys ] |] ),
-              ( "uplus", 1, \[xs] -> [| [ x | x <- toNum $xs ] |] ),
-              ( "uminus", 1, \[xs] -> [| [ case x of XInt n -> XInt (-n); XFloat n -> XFloat (-n) | x <- toNum $xs ] |] ),
-              ( "and", 2, \[xs,ys] -> [| if (conditionTest $xs) && (conditionTest $ys) then [trueXT] else [falseXT] |] ),
-              ( "or", 2, \[xs,ys] -> [| if (conditionTest $xs) || (conditionTest $ys) then [trueXT] else [falseXT] |] ),
-              ( "not", 1, \[xs] -> [| if (conditionTest $xs) then [falseXT] else [trueXT] |] ),
-              ( "some", 1, \[xs] -> [| if (conditionTest $xs) then [trueXT] else [falseXT] |] ),
-              ( "count", 1, \[xs] -> [| [ XInt (length $xs) ] |] ),
-              ( "sum", 1, \[xs] -> [| [ XFloat (sum [ toFloat x | x <- toNum $xs ]) ] |] ),
-              ( "avg", 1, \[xs] -> [| [ XFloat (mean [ toFloat x | x <- toNum $xs ]) ] |] ),
-              ( "min", 1, \[xs] -> [| [ XFloat (minimum [ toFloat x | x <- toNum $xs ]) ] |] ),
-              ( "max", 1, \[xs] -> [| [ XFloat (maximum [ toFloat x | x <- toNum $xs ]) ] |] ),
-              ( "to", 2, \[xs,ys] -> [| [ XInt i | XInt n <- toNum $xs, XInt m <- toNum $ys, i <- [n..m] ] |] ),
-              ( "text", 1, \[xs] -> [| text $xs |] ),
-              ( "string", 1, \[xs] -> [| text $xs |] ),
-              ( "data", 1, \[xs] -> [| text $xs |] ),
-              ( "node", 1, \[xs] -> [| [ w | w@(XElem _ _ _ _ _) <- $xs ] |] ),
-              ( "exists", 1, \[xs] -> [| [ XBool (not (null $xs)) ] |] ),
-              ( "empty", 0, \[] -> [| [] |] ),
-              ( "true", 0, \[] -> [| [trueXT] |] ),
-              ( "false", 0, \[] -> [| [] |] ),
-              ( "if", 3, \[cs,ts,es] -> [| if conditionTest $cs then $ts else $es |] ),
-              ( "element", 2, \[tags,xs] -> [| [ x | tag <- toString $tags, x@(XElem t _ _ _ _) <- $xs, (t==tag || tag=="*") ] |] ),
-              ( "attribute", 2, \[tags,xs] -> [| [ z | tag <- toString $tags, x <- $xs, z <- attribute_step tag x ] |] ),
-              ( "name", 1, \[xs] -> [| [ XText tag | XElem tag _ _ _ _ <- $xs ] |] ),
-              ( "contains", 2, \[xs,text] -> [| [ trueXT | x <- toString $xs, t <- toString $text, contains x t ] |] ),
-              ( "substring", 3, \[xs,n1,n2] -> [| [ XText (take m2 (drop (m1-1) x)) | x <- toString $xs,
-                                                    XInt m1 <- toNum $n1, XInt m2 <- toNum $n2 ] |] ),
-              ( "concatenate", 2, \[xs,ys] -> [| $xs ++ $ys |] ),
-              ( "distinct-values", 1, \[xs] -> [| distinct $xs |] ),
-              ( "union", 2, \[xs,ys] -> [| distinct ($xs ++ $ys) |] ),
-              ( "intersect", 2, \[xs,ys] -> [| filter (\x -> elem x $ys) $xs |] ),
-              ( "except", 2, \[xs,ys] -> [| filter (\x -> not (elem x $ys)) $xs  |] ),
-              ( "reverse", 1, \[xs] -> [| reverse $xs |] )
-            ]
-
-
--- functions to be used by the interpreter
--- when evaluated, it gives [(String,Int,[XSeq]->XSeq)]
-iFunctions :: Q Exp
-iFunctions = foldr (\(fname,len,f) r
-                        -> let vars = map (\i -> mkName ("v_"++(show i))) [1..len]
-                               entry = tupE [litE (StringL fname),litE (IntegerL (toInteger len)),
-                                             lamE [listP (map varP vars)] (f (map varE vars))]
-                           in [| $entry : $r |]) [| [] |] functions
-
-
--- XPath steps to be used by the interpreter
--- when evaluated, it gives [(String,Tag->XTree->XSeq)]
-pFunctions = foldr (\(pname,p) r -> let pn = litE (StringL pname) in [| ($pn,$p) : $r |]) [| [] |] paths
-
-
--- make a function call
-callF :: Tag -> Function
-callF fname args = case filter (\(n,_,_) -> n == fname || ("fn:"++n)==fname) functions of
-                     (_,len,f):_ -> if (length args) == len
-                                       then f args
-                                    else error ("wrong number of arguments in function call: " ++ fname)
-                     _ ->     -- otherwise, it must be a Haskell function of type (XSeq,...,XSeq) -> XSeq
-                          let itp = case args of
-                                      [] -> [t| () |]
-                                      [_] -> [t| XSeq |]
-                                      _ -> foldr (\_ r -> appT r [t| XSeq |]) (appT (tupleT (length args)) [t| XSeq |])
-                                                 (tail args)
-                              fn = sigE (varE (mkName fname))
-                                        (appT (appT arrowT itp) [t| XSeq |])
-                          in appE fn (tupE args)
-
-
-{------------ Compiler ---------------------------------------------------------------}
-
-
-undef1 = [| error "Undefined XQuery context (.)" |]
-undef2 = [| error "Undefined position()" |]
-undef3 = [| error "Undefined last()" |]
-
-
--- does the expression contain a last()?
-containsLast :: Ast -> Bool
-containsLast (Ast "call" [Avar "last"]) = True
-containsLast (Ast f _) | elem f ["let","for","predicate"] = False
-containsLast (Ast "step" _) = False
-containsLast (Ast _ args) = or (map containsLast args)
-containsLast _ = False
-
-
--- calculate the maximum position value used in a predicate, if there is one
-maxPosition :: Ast -> Ast -> Int
-maxPosition position e
-    = case e of
-        Ast "call" [Avar f,p,Aint n]
-            | f `elem` ["=","<","<=","eq","lt","le"] && p == position
-            -> n
-        Ast "call" [Avar f,Aint n,p]
-            | f `elem` ["=",">",">=","eq","gt","ge"] && p == position
-            -> n
-        Ast "let" [Avar x,source,body]
-            -> if position == Avar x
-               then 0 else minp (maxPosition position source) (maxPosition position body)
-        Ast "for" [Avar x,Avar i,source,body]
-            -> if position == Avar x || position == Avar i
-               then 0 else minp (maxPosition position source) (maxPosition position body)
-        Ast "predicate" [pred,body]
-            -> minp (maxPosition position pred) (maxPosition position body)
-        Ast "call" [Avar "and",x,y]
-            -> minp (maxPosition position x) (maxPosition position y)
-        Ast "call" [Avar "or",x,y]
-            -> max (maxPosition position x) (maxPosition position y)
-        _ -> 0
-    where minp x y = if x == 0 then y else if y == 0 then x else min x y
-
-
-pathPosition = Ast "call" [Avar "position"]
-
-
-parent_error = error "constructed elements have no parent"
-
-
--- extract the QName
-qName :: XSeq -> Tag
-qName [XText s] = s
-qName e = error ("Invalid QName: "++(show e))
-
-
--- Each XPath predicate must calculate position() and last() from its input XSeq
--- if last() is used, then the evaluation is blocking (need to store the whole input XSeq)
-compilePredicates :: [Ast] -> Q Exp -> Bool -> Q Exp
-compilePredicates [] xs _ = xs
-compilePredicates ((Aint n):preds) xs _   -- shortcut that improves laziness
-    = compilePredicates preds
-            [| [ $xs !! $(litE (IntegerL (toInteger (n-1)))) ] |] True
-compilePredicates (pred:preds) xs True    -- top-k like
-    | maxPosition pathPosition pred > 0
-    = compilePredicates (pred:preds)
-           [| take $(litE (IntegerL (toInteger (maxPosition pathPosition pred)))) $xs |] False
-compilePredicates (pred:preds) xs _
-    | containsLast pred         -- blocking: use only when last() is used in the predicate
-    = compilePredicates preds
-            [| let bl = $xs
-                   len = length bl
-               in foldir (\x i r -> if case $(compile pred [| x |] [| [XInt i] |] [| [XInt len] |] "") of
-                                         [XInt k] -> k == i               -- indexing
-                                         b -> conditionTest b
-                                    then x:r else r) [] bl 1 |] True
-compilePredicates (pred:preds) xs _
-    = compilePredicates preds
-            [| foldir (\x i r -> if case $(compile pred [| x |] [| [XInt i] |] undef3 "") of
-                                      [XInt k] -> k == i               -- indexing
-                                      b -> conditionTest b
-                                 then x:r else r) [] $xs 1 |] True
-
-
--- Compile the AST e into Haskell code
--- context: context node (XPath .)
--- position: the element position in the parent sequence (XPath position())
--- last: the length of the parent sequence (XPath last())
--- effective_axis: the XPath axis in /axis::tag(exp)
---        (eg, the effective axis of //(A | B) is "descendant_step"
-compile :: Ast -> Q Exp -> Q Exp -> Q Exp -> String -> Q Exp
-compile e context position last effective_axis
-  = case e of
-      Avar "." -> [| [ $context :: XTree ] |]
-      Avar v -> let x = varE (mkName v)
-                in [| $x :: XSeq |]
-      Aint n -> let x = litE (IntegerL (toInteger n))
-                in [| [ XInt $x ] |]
-      Afloat n -> let x = litE (RationalL (toRational n))
-                  in [| [ XFloat $x ] |]
-      Astring s -> let x = litE (StringL s)
-                   in [| [ XText $x ] |]
-      Ast "context" [v,Astring dp,body]
-          -> [| foldr (\x r -> $(compile body [| x |] position last dp)++r)
-                      [] $(compile v context position last effective_axis) |]
-      Ast "call" [Avar "position"]
-          -> position
-      Ast "call" [Avar "last"]
-          -> last
-      Ast "child_step" [tag, Avar "."]
-          | effective_axis /= ""
-          -> compile (Ast effective_axis [tag, Avar "."]) context position last ""
-      Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
-          -> let bc = compile body context position last effective_axis
-                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
-             in [| foldr (\x r -> $(compilePredicates predicates [| descendant_any_with_tagged_children $ts x |] True)++r)
-                         [] $bc |]
-      Ast "step" ((Ast path_step [Astring tag,body]):predicates)
-          |  memV path_step paths
-          -> let bc = compile body context position last effective_axis
-                 tc = litE (stringL tag)
-             in [| foldr (\x r -> $(compilePredicates predicates [| $(findV path_step paths) $tc x |] True)++r)
-                         [] $bc |]
-      Ast "descendant_any" (body:tags)
-          -> let bc = compile body context position last effective_axis
-                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
-             in [| foldr (\x r -> (descendant_any_with_tagged_children $ts x)++r) [] $bc |]
-      Ast path_step [Astring tag,body]
-          |  memV path_step paths
-          -> let bc = compile body context position last effective_axis
-                 tc = litE (stringL tag)
-             in [| foldr (\x r -> ($(findV path_step paths) $tc x)++r) [] $bc |]
-      Ast "step" (exp:predicates)
-          -> compilePredicates predicates (compile exp context position last effective_axis) True
-      Ast "predicate" [condition,body]
-          -> compilePredicates [condition] (compile body context position last effective_axis) True
-      Ast "append" args
-          -> [| appendText $(listE (map (\x -> compile x context position last effective_axis) args)) |]
-      Ast "call" ((Avar f):args)
-          -> callF f (map (\x -> compile x context position last effective_axis) args)
-      Ast "construction" [Astring tag,Ast "attributes" [],body]
-          -> let ct = litE (StringL tag)
-                 bc = compile body context position last effective_axis
-             in [| [ XElem $ct [] 0 parent_error $bc ] |]
-      Ast "construction" [tag,Ast "attributes" al,body]
-          -> let alc = foldr (\(Ast "pair" [a,v]) r
-                                  -> let ac = compile a context position last effective_axis
-                                         vc = compile v context position last effective_axis
-                                     in [| (qName $ac,showXS $vc) : $r |]) [| [] |] al
-                 ct = compile tag context position last effective_axis
-                 bc = compile body context position last effective_axis
-             in [| [ XElem (qName $ct) $alc 0 parent_error $bc ] |]
-      Ast "let" [Avar var,source,body]
-          -> do s <- compile source context position last effective_axis
-                b <- compile body context position last effective_axis
-                return (AppE (LamE [VarP (mkName var)] b) s)
-      Ast "for" [Avar var,Avar "$",source,body]      -- a for-loop without an index
-          -> let b = compile body [| head $(varE (mkName var)) |] undef2 undef3 ""
-                 f = lamE [varP (mkName var)] [| \r -> $b ++ r |]
-                 s = compile source context position last effective_axis
-             in [| foldr (\x -> $f [x]) [] $s |]
-      Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
-          -> let b = compile body [| head $(varE (mkName var)) |]
-                             [| $(varE (mkName ivar)) |] undef3 ""
-                 f = lamE [varP (mkName var)] (lamE [varP (mkName ivar)] [| \r -> $b ++ r |])
-                 p = maxPosition (Avar ivar) body
-                 ns = if p > 0              -- there is a top-k like restriction
-                      then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
-                      else source
-                 s = compile ns context position last effective_axis
-             in [| foldir (\x i -> $f [x] [XInt i]) [] $s 1 |]
-      Ast "sortTuple" (exp:orderBys)             -- prepare each FLWOR tuple for sorting
-          -> let res = foldl (\r a -> let ac = compile a context position last effective_axis
-                                      in [| $r++[text $ac] |] )
-                             [| [ $(compile exp context position last effective_axis) ] |] orderBys
-             in [| [ $res ] |]
-      Ast "sort" (exp:ordList)                   -- blocking
-          -> let ce = compile exp context position last effective_axis
-                 ordering = foldr (\(Avar ord) r
-                                       -> let asc = if ord == "ascending"
-                                                    then [| True |]
-                                                    else [| False |]
-                                          in [| \(x:xs) (y:ys) -> case compareXSeqs $asc x y of
-                                                                    EQ -> $r xs ys
-                                                                    o -> o |])
-                                  [| \xs ys -> EQ |] ordList
-             in [| concatMap head (sortBy (\(_:xs) (_:ys) -> $ordering xs ys) ($ce::[[XSeq]])) |]
-      _ -> error ("Illegal XQuery: "++(show e))
-
-
--- The monadic compilePredicates that propagates IO state
-compilePredicatesM :: [Ast] -> Q Exp -> Bool -> Q Exp
-compilePredicatesM [] xs _
-    = [| return $xs |]
-compilePredicatesM ((Aint n):preds) xs _   -- shortcut that improves laziness
-    = compilePredicatesM preds
-            [| [ $xs !! $(litE (IntegerL (toInteger (n-1)))) ] |] True
-compilePredicatesM (pred:preds) xs True    -- top-k like
-    | maxPosition pathPosition pred > 0
-    = compilePredicatesM (pred:preds)
-           [| take $(litE (IntegerL (toInteger (maxPosition pathPosition pred)))) $xs |] False
-compilePredicatesM (pred:preds) xs _
-    | containsLast pred         -- blocking: use only when last() is used in the predicate
-    = [| do let bl = $xs
-                last = length bl
-            vs <- foldir (\x i r -> do vs <- $(compileM pred [| x |] [| [XInt i] |] [| [XInt last] |] "")
-                                       s <- r
-                                       return (if case vs of
-                                                    [XInt k] -> k == i               -- indexing
-                                                    b -> conditionTest b
-                                               then x:s else s))
-                         (return []) $xs 1
-            $(compilePredicatesM preds [| vs |] True) |]
-compilePredicatesM (pred:preds) xs _
-    = [| do vs <- foldir (\x i r -> do vs <- $(compileM pred [| x |] [| [XInt i] |] undef3 "")
-                                       s <- r
-                                       return (if case vs of
-                                                    [XInt k] -> k == i               -- indexing
-                                                    b -> conditionTest b
-                                               then x:s else s))
-                         (return []) $xs 1
-            $(compilePredicatesM preds [| vs |] True) |]
-
-
--- The monadic XQuery compiler; it is like compile but has plumbing to propagate IO state
-compileM :: Ast -> Q Exp -> Q Exp -> Q Exp -> String -> Q Exp
-compileM e context position last effective_axis
-  = case e of
-      Avar "." -> [| return [ $context :: XTree ] |]
-      Avar v -> let x = varE (mkName v)
-                in [| return ($x :: XSeq) |]
-      Aint n -> let x = litE (IntegerL (toInteger n))
-                in [| return [ XInt $x ] |]
-      Afloat n -> let x = litE (RationalL (toRational n))
-                  in [| return [ XFloat $x ] |]
-      Astring s -> let x = litE (StringL s)
-                   in [| return [ XText $x ] |]
-      -- for non-IO XQuery, use the regular compile
-      Ast "nonIO" [u] -> [| return $(compile u context position last effective_axis) |]
-      Ast "context" [v,Astring dp,body]
-          -> [| do vs <- $(compileM v context position last effective_axis)
-                   foldr (\x r -> (liftM2 (++)) $(compileM body [| x |] position last dp) r)
-                         (return []) vs |]
-      Ast "call" [Avar "position"]
-          -> [| return $position |]
-      Ast "call" [Avar "last"]
-          -> [| return $last |]
-      Ast "child_step" [tag, Avar "."]
-          | effective_axis /= ""
-          -> compileM (Ast effective_axis [tag, Avar "."]) context position last ""
-      Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
-          -> let bc = compileM body context position last effective_axis
-                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
-             in [| do vs <- $bc
-                      foldr (\x r -> (liftM2 (++)) $(compilePredicatesM predicates
-                                                         [| descendant_any_with_tagged_children $ts x |] True) r)
-                            (return []) vs |]
-      Ast "step" ((Ast path_step [Astring tag,body]):predicates)
-          |  memV path_step paths
-          -> let bc = compileM body context position last effective_axis
-                 tc = litE (stringL tag)
-             in [| do vs <- $bc
-                      foldr (\x r -> (liftM2 (++)) $(compilePredicatesM predicates
-                                                           [| $(findV path_step paths) $tc x |] True) r)
-                            (return []) vs |]
-      Ast "descendant_any" (body:tags)
-          -> let bc = compileM body context position last effective_axis
-                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
-             in [| do vs <- $bc
-                      return (foldr (\x r -> (descendant_any_with_tagged_children $ts x)++r) [] vs) |]
-      Ast path_step [Astring tag,body]
-          |  memV path_step paths
-          -> let bc = compileM body context position last effective_axis
-                 tc = litE (stringL tag)
-             in [| do vs <- $bc
-                      return (foldr (\x r -> ($(findV path_step paths) $tc x)++r) [] vs) |]
-      Ast "step" (exp:predicates)
-          -> [| do vs <- $(compileM exp context position last effective_axis)
-                   $(compilePredicatesM predicates [| vs |] True) |]
-      Ast "predicate" [condition,body]
-          -> [| do vs <- $(compileM body context position last effective_axis)
-                   $(compilePredicatesM [condition] [| vs |] True) |]
-      Ast "executeSQL" [Avar stmt,args]
-          -> [| do as <- $(compileM args context position last effective_axis)
-                   $(varE (mkName "executeSQL")) $(varE (mkName stmt)) as |]
-      Ast "append" args
-          -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args
-             in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])
-                      [| return (appendText $(listE (map (\(n,_) -> varE n) binds))) |] binds
-      Ast "call" ((Avar f):args)
-          -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args
-             in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])
-                      [| return $(callF f (map (\(n,_) -> varE n) binds)) |] binds
-      Ast "construction" [Astring tag,Ast "attributes" [],body]
-          -> let ct = litE (StringL tag)
-                 bc = compileM body context position last effective_axis
-             in [| do b <- $bc
-                      return [ XElem $ct [] 0 parent_error b ] |]
-      Ast "construction" [tag,Ast "attributes" al,body]
-          -> let alc = foldr (\(Ast "pair" [a,v]) r
-                                  -> [| do ac <- $(compileM a context position last effective_axis)
-                                           vc <- $(compileM v context position last effective_axis)
-                                           s <- $r
-                                           return ((qName ac,showXS vc):s) |]) [| return [] |] al
-                 ct = compileM tag context position last effective_axis
-                 bc = compileM body context position last effective_axis
-             in [| do a <- $alc
-                      c <- $ct
-                      b <- $bc
-                      return [ XElem (qName c) a 0 parent_error b ] |]
-      Ast "let" [Avar var,source,body]
-          -> [|  $(compileM source context position last effective_axis)
-                 >>= $(lamE [varP (mkName var)] (compileM body context position last effective_axis)) |]
-      Ast "for" [Avar var,Avar "$",source,body]      -- a for-loop without an index
-          -> let b = compileM body [| head $(varE (mkName var)) |] undef2 undef3 ""
-                 f = lamE [varP (mkName var)] [| (liftM2 (++)) $b |]
-                 s = compileM source context position last effective_axis
-             in [| do vs <- $s
-                      foldr (\x -> $f [x]) (return []) vs |]
-      Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
-          -> let b = compileM body [| head $(varE (mkName var)) |]
-                             [| $(varE (mkName ivar)) |] undef3 ""
-                 f = lamE [varP (mkName var)] (lamE [varP (mkName ivar)] [| (liftM2 (++)) $b |])
-                 p = maxPosition (Avar ivar) body
-                 ns = if p > 0              -- there is a top-k like restriction
-                      then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
-                      else source
-                 s = compileM ns context position last effective_axis
-             in [| do vs <- $s
-                      foldir (\x i -> $f [x] [XInt i]) (return []) vs 1 |]
-      Ast "sortTuple" (exp:orderBys)             -- prepare each FLWOR tuple for sorting
-          -> let vs = compileM exp context position last effective_axis
-                 res = foldl (\r a -> [| do ac <- $(compileM a context position last effective_axis)
-                                            s <- $r
-                                            return (s++[text ac]) |] )
-                             [| do v <- $vs; return [ v ] |] orderBys
-             in [| return $res |]
-      Ast "sort" (exp:ordList)                   -- blocking
-          -> let ce = compileM exp context position last effective_axis
-                 ordering = foldr (\(Avar ord) r
-                                       -> let asc = if ord == "ascending"
-                                                    then [| True |]
-                                                    else [| False |]
-                                          in [| \(x:xs) (y:ys) -> case compareXSeqs $asc x y of
-                                                                    EQ -> $r xs ys
-                                                                    o -> o |])
-                                  [| \xs ys -> EQ |] ordList
-             in [| do c <- $ce
-                      return (concatMap head (sortBy (\(_:xs) (_:ys) -> $ordering xs ys) (c::[[XSeq]]))) |]
-      _ -> error ("Illegal XQuery: "++(show e))
-
-
--- functions that need IO interaction (document reader, DB access, etc)
-ioSources :: [ String ]
-ioSources = ["executeSQL","doc","fn:doc","sql","fn:sql","publish","fn:publish"]
-
-
--- collect all input documents and assign them a unique number
-pullIOSources :: Ast -> Int -> (Ast, Int, [(String, Ast)])
-pullIOSources query count
-    = case query of
-             Ast "call" [Avar nm,file]
-                 | elem nm ["doc","fn:doc"]
-                 -> (Avar ("_doc"++(show count)), count+1, [("_doc"++(show count),file)])
-             Ast "call" [Avar nm,sql]
-                 | elem nm ["sql","fn:sql"]
-                 -> (Ast "executeSQL" [Avar ("_sql"++(show count)),Ast "call" [Avar "empty"]], count+1,
-                     [("_sql"++(show count),Ast "prepareSQL" [sql])])
-             Ast "call" [Avar nm,sql,args]
-                 | elem nm ["sql","fn:sql"]
-                 -> (Ast "executeSQL" [Avar ("_sql"++(show count)),args], count+1,
-                     [("_sql"++(show count),Ast "prepareSQL" [sql])])
-             Ast n args
-                 -> let (s,c,ns) = foldr (\a r c -> let (e,c1,n1) = pullIOSources a c
-                                                        (s,c2,n2) = r c1
-                                                    in (e:s,c2,union n1 n2))
-                                         (\c -> ([],c,[])) args count
-                    in (Ast n s,c,ns)
-             _ -> (query,count,[])
-    where union xs ((n,s):ys) = (n,foldr(\(m,d) r -> if s==d then Avar m else r) s xs):(union xs ys)
-          union xs [] = xs
-
-
--- true if there is no need to lift to the IO monad
-noIO :: Ast -> Bool
-noIO (Ast nm _) | elem nm ioSources = False
-noIO (Ast n args) = all noIO args
-noIO _ = True
-
-
-liftIOSources :: Ast  -> (Ast, [(String, Ast)])
-liftIOSources query
-    = let (ast,_,ns) = pullIOSources query 0
-          f x = case x of
-                  Ast nm _ | elem nm ["attributes"] -> x
-                  Ast _ _ | noIO x -> Ast "nonIO" [x]
-                  _ -> case x of
-                         Ast "call" ((Avar nm):args)
-                             -> Ast "call" ((Avar nm):(map f args))
-                         Ast n args -> Ast n (map f args)
-                         _ -> x
-      in (f ast,ns)
-
-
--- optimize and compile an AST (unlifted)
-compileAst :: Ast -> Q Exp
-compileAst ast = compile (optimize ast) undef1 undef2 undef3 ""
-
-
--- optimize and compile an AST (IO lifted)
-compileAstM :: Ast -> Q Exp
-compileAstM ast = compileM (optimize ast) undef1 undef2 undef3 ""
-
-
--- compile an XQuery AST that reads XML documents
-compileQuery :: [Ast] -> Q Exp
-compileQuery ((Ast "function" ((Avar f):b:args)):xs)
-    = let lvars = case args of
-                    [Astring a] -> [varP (mkName a)]
-                    _ -> [tupP (map (\(Avar a) -> varP (mkName a)) args)]
-      in letE [valD (varP (mkName f)) (normalB (lamE lvars (compileAst b))) []]
-              (compileQuery xs)
-compileQuery ((Ast "variable" [Avar v,u]):xs)
-    = letE [valD (varP (mkName v)) (normalB (compileAst u)) []]
-           (compileQuery xs)
-compileQuery [query]
-    = let (ast,ns) = liftIOSources (optimize query)
-          code = compileM ast undef1 undef2 undef3 ""
-      in foldl (\r (n,e) -> let d = lamE [varP (mkName n)] r
-                            in case e of
-                                 Avar m -> [| $d $(varE (mkName m)) |]
-                                 Ast "prepareSQL" [Astring sql]
-                                     -> [| ($(varE (mkName "prepareSQL"))
-                                                    $(varE (mkName "_db"))
-                                                    $(litE (StringL sql))) >>= $d |]
-                                 _ -> [| do let [XText f] = $(compileAst e)
-                                            doc <- readFile f
-                                            $d [materialize (parseDocument doc)] |])
-               [| $code |] ns
-
-
--- Debugging: display the AST and the Haskell code of an input XQuery
-cq :: String -> IO ()
-cq query = do putStrLn "Abstract Syntax Tree:"
-              let ast = parse (scan query)
-              putStrLn (show ast)
-              let opt = optimize (last ast)
-              putStrLn "Optimized AST:"
-              putStrLn (show opt)
-              --putStrLn "Haskell Code:"
-              --let code = compileQuery ast
-              --runQ code >>= putStrLn.pprint
-
-
--- | Run an XQuery expression that does not read XML documents.
--- When evaluated, it returns XSeq.
-xe :: String -> Q Exp
-xe query = compileAst (last (parse (scan query)))
-
-
--- | Run an XQuery that reads XML documents.
--- When evaluated, it returns IO XSeq.
-xq :: String -> Q Exp
-xq query = compileQuery (parse (scan query))
-
-
--- | Run an XQuery that reads XML documents and queries databases.
--- When evaluated, it returns (IConnection conn) => conn -> IO XSeq.
-xqdb :: String -> Q Exp
-xqdb query = lamE [varP (mkName "_db")] (compileQuery (parse (scan query)))
diff --git a/XML/HXQ/DB.hs b/XML/HXQ/DB.hs
deleted file mode 100644
--- a/XML/HXQ/DB.hs
+++ /dev/null
@@ -1,485 +0,0 @@
-{-------------------------------------------------------------------------------------
--
-- Database connectivity using HDBC
-- Programmer: Leonidas Fegaras
-- Email: fegaras@cse.uta.edu
-- Web: http://lambda.uta.edu/
-- Creation: 05/12/08, last update: 06/12/08
-- 
-- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
-- This material is provided as is, with absolutely no warranty expressed or implied.
-- Any use is at your own risk. Permission is hereby granted to use or copy this program
-- for any purpose, provided the above notices are retained on all copies.
--
---------------------------------------------------------------------------------------}
-
-
-module XML.HXQ.DB where
-
-import Char(isSpace,toLower)
-import Control.Monad.State
-import Database.HDBC
-import XML.HXQ.XTree
-import XMLParse(XMLEvent(..),parseDocument)
-import HXML(AttList)
-import XML.HXQ.Parser
-
-
-sql2xml :: SqlValue -> XTree
-sql2xml value =
-    case value of
-      SqlString s -> XText s
-      SqlByteString bs -> XText (show bs)
-      SqlWord32 n -> XInt (fromEnum n)
-      SqlWord64 n -> XInt (fromEnum n)
-      SqlInt32 n -> XText (show n)
-      SqlInt64 n -> XText (show n)
-      SqlInteger n -> XInt (fromEnum n)
-      SqlChar c -> XText [c]
-      SqlBool b -> XBool b
-      SqlDouble n -> XText (show n)
-      SqlRational n -> XText (show n)
-      SqlEpochTime n -> XText (show n)
-      SqlTimeDiff n -> XText (show n)
-      SqlNull -> XText ""
-
-
-xml2sql :: XTree -> SqlValue
-xml2sql e =
-    case e of
-      XText s -> SqlString s
-      XInt n -> SqlInteger (toInteger n)
-      XFloat n -> SqlString (show n)
-      XBool n -> SqlBool n
-      XElem n _ _ _ [x] -> xml2sql x
-      _ -> error ("Cannot convert "++show e++" into sql")
-
-
-perror = error "constructed elements have no parent"
-
-
-executeSQL :: Statement -> XSeq -> IO XSeq
-executeSQL stmt args
-    = do n <- handleSqlError (execute stmt (map xml2sql args))
-         result <- handleSqlError (fetchAllRowsAL stmt)
-         return (map (\x -> XElem "row" [] 0 perror (map (\(s,v) -> XElem s [] 0 perror [sql2xml v]) x)) result)
-
-
-prepareSQL :: (IConnection conn) => conn -> String -> IO Statement
-prepareSQL db sql = handleSqlError (prepare db sql)
-
-
-{---------------------------------------------------------------------------------------
--- extract the structural summary of an XML file that contains statistics
-----------------------------------------------------------------------------------------}
-
-
--- structural summary: tag   id  max#      hasText children
-data SSnode = SSnode String !Int !Int !Int !Bool   [SSnode]
-            deriving (Eq,Show)
-
-
-insertSS :: String -> [SSnode] -> State Int (Int,SSnode,[SSnode])
-insertSS tag ((SSnode n i j l b ts):s)
-    | n == tag
-    = return (i,SSnode n i j (l+1) b ts,s)
-insertSS tag (x:xs)
-    = do (i,t,ts) <- insertSS tag xs
-         return (i,t,x:ts)
-insertSS tag []
-    = do count <- get
-         put (count+1)
-         return (count+1,SSnode tag (count+1) 1 1 False [],[])
-
-
-insSS :: String -> [SSnode] -> State Int [SSnode]
-insSS tag ns = do (k,t,s) <- insertSS tag ns
-                  return (t:s)
-
-
-getSS :: [XMLEvent] -> [SSnode] -> State Int [SSnode]
-getSS ((EmptyEvent n atts):xs) rs
-    = getSS ((StartEvent n atts):(EndEvent n):xs) rs
-getSS ((StartEvent n atts):xs) ((SSnode m i j l b ns):rs)
-    = do (k,SSnode m' i' j' l' b' ks,ts) <- insertSS n ns
-         as <- foldM (\r (a,_) -> insSS ('@':a) r) ks atts
-         getSS xs (reset(SSnode m' i' j' l' b' as):(SSnode m i j l b ts):rs)
-    where r (SSnode m i j _ b ts) = SSnode m i j 0 b ts
-          reset (SSnode m i j l b ts) = SSnode m i j l b (map r ts)
-getSS ((EndEvent n):xs) (t:(SSnode m i j l b ns):rs)
-    = getSS xs ((SSnode m i j l b (set t:ns):rs))
-    where s (SSnode m i j l b ts) = SSnode m i (max j l) 0 b ts
-          set (SSnode m i j l b ts) = SSnode m i j l b (map s ts)
-getSS ((TextEvent t):xs) ((SSnode m i j l False ns):rs)
-    | any (not . isSpace) t
-    = getSS xs ((SSnode m i j l True ns):rs)
-getSS (_:xs) rs = getSS xs rs
-getSS [] rs = return rs
-
-
-{---------------------------------------------------------------------------------------
--- Derive a good relational schema based on the structural summary (using hybrid inlining)
-----------------------------------------------------------------------------------------}
-
-
-type Path = [Tag]
-
-
-data Table = Table String Path Bool [Table]
-           | Column String Path
-           deriving (Show,Read)
-
-
-printPath :: Path -> String
-printPath [] = ""
-printPath [p] = p
-printPath (p:ps) = printPath ps++"/"++p
-
-
-pathCons p ps = if p=="root" then ps else p:ps
-
-
-schema :: SSnode -> String -> [String] -> [Table]
-schema (SSnode n i _ (-1) _ ts) prefix path
-    = [ Table (prefix++show i) (pathCons n path) True
-              ((reverse (concatMap (\t -> schema t prefix []) ts))
-               ++[ Column "value" [] ]) ]
-schema (SSnode n i j _ _ []) prefix path
-    | j == 1 || head n == '@'
-    = [ Column (prefix++show i) (pathCons n path) ]
-schema (SSnode n i 1 _ _ ts) prefix path
-    = concatMap (\t -> schema t prefix (pathCons n path)) ts
-schema (SSnode n i _ _ b ts) prefix path
-    = [ Table (prefix++show i) (pathCons n path) False
-              ((reverse (concatMap (\t -> schema t prefix []) ts))
-              ++(if b && all (\(SSnode x _ _ _ _ _)-> head x == '@') ts
-                 then [ Column "value" [] ] else [])) ]
-
-
-fixSS :: SSnode -> SSnode
-fixSS (SSnode n i j l True ts)
-    | any (\(SSnode x _ _ _ _ _)-> head x /= '@') ts
-    = SSnode n i j (-1) True (filter (\(SSnode x _ _ _ _ _)-> head x == '@') ts)
-fixSS (SSnode n i j l b ts)
-    = SSnode n i j l b (map fixSS ts)
-
-
-deriveSchema :: String -> String -> IO Table
-deriveSchema file prefix
-    = do doc <- readFile file
-         let ts = parseDocument doc
-             d = getSS ts [SSnode "root" 1 1 1 False []]
-             [SSnode _ _ _ _ _ [t]] = evalState d 1
-             nt@(SSnode m i j l b s) = fixSS t
-         return (Table prefix [] False (reverse (schema (SSnode m i 2 l b s) prefix [])))
-
-
-relationalSchema :: Table -> String -> [String]
-relationalSchema (Table n path b ts) parent
-    = ("create table "++n++" (      /* "++printPath path
-       ++(if b then " (mixed content)" else "")++" */\n"
-       ++n++"_id int,\n"
-       ++(if parent /= "" then (n++"_parent int references "++parent++"("++parent++"_id),\n") else "")
-       ++(concat [ m++" varchar,    /* "++printPath p++" */\n" | Column m p <- ts ])
-       ++"primary key ("++n++"_id))\n")
-      :[ s | t@(Table _ _ _ _) <- ts, s <- relationalSchema t n ]
-
-
-getTableNames :: Table -> [String]
-getTableNames (Table n _ _ ts) = n:(concatMap getTableNames ts)
-getTableNames _ = []
-
-
-initializeDB :: (IConnection conn) => conn -> IO ()
-initializeDB db
-    = do tables <- getTables db
-         if elem "HXQCatalog" tables
-            then return ()
-            else do let s = "create table HXQCatalog ( name varchar primary key, path varchar, summary varchar )"
-                    handleSqlError (run db s [])
-                    commit db
-
-
-createSchema :: (IConnection conn) => conn -> String -> String -> IO Table
-createSchema db file name
-    = do initializeDB db
-         stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")
-         _ <- handleSqlError (execute stmt  [SqlString name])
-         result <- handleSqlError (fetchAllRowsAL stmt)
-         if length result > 0
-            then do let [[(_,SqlString s)]] = result
-                        summary = (read s)::Table
-                        tables = getTableNames summary
-                    _ <- mapM (\t -> handleSqlError (run db ("drop table if exists "++t) [])) tables
-                    _ <- handleSqlError (run db "delete from HXQCatalog where name = ?" [SqlString name])
-                    commit db
-            else return ()
-         t <- deriveSchema file name
-         let schema = relationalSchema t ""
-         -- mapM putStrLn schema
-         _ <- handleSqlError (run db "insert into HXQCatalog values (?,?,?)"
-                                      [SqlString name, SqlString file, SqlString (show t)])
-         _ <- mapM (\s -> handleSqlError (run db s [])) schema
-         commit db
-         return t
-
-
-findSchema :: (IConnection conn) => conn -> String -> IO Table
-findSchema db name
-    = do initializeDB db
-         stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")
-         _ <- handleSqlError (execute stmt  [SqlString name])
-         result <- handleSqlError (fetchAllRowsAL stmt)
-         if length result == 1
-            then let [[(_,SqlString s)]] = result
-                 in return ((read s)::Table)
-            else error ("Schema "++name++" doesn't exist")
-
-
-{---------------------------------------------------------------------------------------
--- Populate the database from the XML file and its derived structural summary
-----------------------------------------------------------------------------------------}
-
-
-findPath :: [Table] -> [String] -> Int -> Maybe (Int,Table)
-findPath (t@(Table _ p _ s):ts) path _ | p == path = Just ((length s)-1,t)
-findPath (t@(Column _ p):ts) path n | p == path = Just (n,t)
-findPath ((Table _ _ _ _):ts) path n = findPath ts path n
-findPath (_:ts) path n = findPath ts path (n+1)
-findPath [] _ _ = Nothing
-
-
-populate :: [XMLEvent] -> [Table] -> Int -> [[String]] -> [(Int,String)]
-populate ((EmptyEvent tag atts):xs) ts n ps
-    = populate ((StartEvent tag atts):(EndEvent tag):xs) ts n ps
-populate (x@(StartEvent tag atts):xs) ((t@(Table n path _ s)):ts) _ (p:ps)
-    = case findPath s (tag:p) 0 of
-        Just (n,nt@(Table m _ True as))
-            -> (-1,m):(popAtts atts as ++ showXTree xs 1 "")
-               where showXTree ((EmptyEvent tag atts):xs) i s
-                         = showXTree xs i (s++"<"++tag++showAL atts++"/>")
-                     showXTree ((StartEvent tag atts):xs) i s
-                         = showXTree xs (i+1) (s++"<"++tag++showAL atts++">")
-                     showXTree ((EndEvent tag):xs) i s
-                         = if i==1 then (n,s):(-2,m):(populate xs (t:ts) n (p:ps))
-                           else showXTree xs (i-1) (s++"</"++tag++">")
-                     showXTree ((TextEvent text):xs) i s = showXTree xs i (s++text)
-                     showXTree (_:xs) i s = showXTree xs i s
-        Just (n,nt@(Table m _ _ as))
-            -> (-1,m):((popAtts atts as)++(populate xs (nt:t:ts) n ([]:p:ps)))
-        Just (n,nt)
-            -> populate xs (nt:t:ts) n ((tag:p):ps)
-        Nothing -> populate xs (t:ts) 0 ((tag:p):ps)
-      where popAtts ((a,v):as) ks
-                = let Just(m,_) = findPath ks ['@':a] 0
-                  in (m,v):(popAtts as ks)
-            popAtts [] _ = []
-populate ((EndEvent tag):xs) ((t@(Table n path _ s)):ts) _ ([]:ps)
-    = (-2,n):populate xs ts 0 ps
-populate ((EndEvent tag):xs) ((Column m path):ts) n (p:ps)
-    = populate xs ts 0 (tail p:ps)
-populate ((EndEvent text):xs) ts _ (p:ps)
-    = populate xs ts 0 (tail p:ps)
-populate ((TextEvent text):xs) ts n ps
-    | any (not . isSpace) text
-    = (n,text):populate xs ts n ps
-populate (x:xs) ts n ps
-    = populate xs ts n ps
-populate [] ts n ps = []
-
-
-insert :: (IConnection conn) => conn -> [(Int,String)] -> [(String,Int,Statement)] -> IO ()
-insert db xs stmts = let (s,_,_,_) = m xs 0 0 in s
-    where m ((-1,m):xs) i p = let (s,el,xs',i') = ml xs (i+1) i
-                              in (s >> insertTuple m el i p,[],xs',i')
-          m ((k,m):xs) i p = (return (),[(k,m)],xs,i)
-          ml [] i p = (return (),[],[],i)
-          ml ((-2,m):xs) i p = (return (),[],xs,i)
-          ml xs i p = let (s,el,xs',i') = m xs i p
-                          (s',el',xs'',i'') = ml xs' i' p
-                      in (s >> s',el++el',xs'',i'')
-          find x xs = foldr (\(a,v) r -> if x==a then v else r) "\NUL" xs
-          insertTuple m e i p
-              = let (len,stmt) = foldr (\(a,l,s) r -> if m==a then (l,s) else r) (error "") stmts
-                    tuple = map (\c -> find c e) [0..len]
-                    lift x = if x=="\NUL" then SqlNull else SqlString x
-                in do _ <- handleSqlError (execute stmt
-                                           (if i==0
-                                            then SqlInteger i:(map lift tuple)
-                                            else SqlInteger i:SqlInteger p:(map lift tuple)))
-                      if mod i 100 == 99 then commit db else return ()
-                      return ()
-
-
--- | Store an XML document into the database under the given name.
-shred :: (IConnection conn) => conn -> String -> String -> IO ()
-shred db file name
-    = do let prefix = map toLower name
-         let tableStmt (Table n _ _ ts)
-                 = do let len = length[ 1 | Column _ _ <- ts]-1
-                      stmt <- handleSqlError (prepare db ("insert into "++n++" values ("
-                                                          ++(if n==prefix then "" else "?,")++"?"
-                                                          ++(concatMap (\_ -> ",?") [0..len])++")"))
-                      l <- mapM tableStmt ts
-                      return ((n,len,stmt):(concat l))
-             tableStmt _ = return []
-         t <- createSchema db file prefix
-         stmts <- tableStmt t
-         doc <- readFile file
-         let ts = parseDocument doc
-         let ic = (-1,prefix):(populate ts [t] 0 [[]] ++ [(-2,prefix)])
-         insert db ic stmts
-         commit db
-         return ()
-
-
--- | Create a secondary index on tagname for the shredded document under the given name..
-createIndex :: (IConnection conn) => conn -> String -> String -> IO ()
-createIndex db name tagname
-    = do let prefix = map toLower name
-         table <- findSchema db name
-         let indexes = getIndexes "" table
-         _ <- if null indexes
-              then error ("there is no tagname: "++tagname)
-              else mapM (\(t,c) -> do stmt <- handleSqlError (prepare db ("create index "++t++"_"++c++" on "++t++" ("++c++")"))
-                                      handleSqlError (execute stmt [])) indexes
-         commit db
-         return ()
-    where getIndexes _ (Table n _ _ ts) = concatMap (getIndexes n) ts
-          getIndexes table (Column n path) | (head path)==tagname = [(table,n)]
-          getIndexes _ _ = []
-
-
-{----------------------------------------------------------------------------------------------------
---  Convert XQuery to SQL
-----------------------------------------------------------------------------------------------------}
-
-
-publishES :: [String] -> [String] -> String
-publishES (p:ps) xs
-    | head p == '@'
-    = "attribute "++(tail p)++" {"++publishES ps xs++"}"
-publishES (p:ps) xs
-    = "<"++p++">{"++publishES ps xs++"}</"++p++">"
-publishES [] [x] = x
-publishES [] (x:xs) = x++","++publishES [] xs
-
-
-publishS :: Table -> String -> String
-publishS (Table n path b ts) "error"
-    = "for $"++n++" in SQL(select(),from($"++n++"),true()) return "
-      ++publishES (reverse path) (map (\t -> publishS t n) ts)
-publishS (Table n path b ts) parent
-    = "for $"++n++" in SQL(select(),from($"++n++"),$"++n++"/"++n++"_parent eq $"
-      ++parent++"/"++parent++"_id) return "
-      ++publishES (reverse path) (map (\t -> publishS t n) ts)
-publishS (Column n path) parent
-    = publishES (reverse path) ["$"++parent++"/"++n++"/text()"]
-
-
-publishTable :: Table -> String
-publishTable table = "<root>{" ++ publishS table "error" ++ "}</root>"
-
-
-sqlComparisson = [("=","="),("eq","="),("<=","<="),(">=",">="),("!=","!="),(">",">"),
-                  ("<","<"),("ne","!="),("gt",">"),("lt","<"),("ge",">="),("le","<=")]
-
-sqlBoolean = [("and","and"),("or","or")]
-
-
--- Is this an SQL predicate?
-sqlPredicate :: [String] -> Ast -> Bool
-sqlPredicate tables e
-    = case e of
-        Ast "child_step" [Astring c,Avar v]
-            -> elem v tables
-        Ast "construction" [_,_,Ast "append" [x]]
-            -> sqlPredicate tables x
-        Ast "call" [Avar "text",x]
-            -> sqlPredicate tables x
-        Ast "call" [Avar cmp,x,y]
-            | any (\(f,_) -> f==cmp) sqlComparisson
-            -> (sqlExpr x) && (sqlExpr y)
-        Ast "call" [Avar cmp,x,y]
-            | any (\(f,_) -> f==cmp) sqlBoolean
-            -> (sqlPredicate tables x) && (sqlPredicate tables y)
-        _ -> False
-      where sqlExpr e
-                = case e of
-                    Astring s -> True
-                    Aint n -> True
-                    Ast "child_step" [Astring c,Avar v]
-                        -> elem v tables
-                    Ast "construction" [_,_,Ast "append" [x]]
-                        -> sqlExpr x
-                    Ast "call" [Avar "text",x]
-                        -> sqlExpr x
-                    _ -> False
-
-
--- Convert a predicate AST to an SQL predicate that uses the tables
-predToSQL :: [String] -> Ast -> (String,[Ast])
-predToSQL tables e
-    = case e of
-        Ast "child_step" [Astring c,Avar v]
-            -> if elem v tables
-               then ("",[])
-               else error ("Cannot convert to an SQL predicate: "++show e)
-        Ast "construction" [_,_,Ast "append" [x]]
-            -> predToSQL tables x
-        Ast "call" [Avar "text",x]
-            -> predToSQL tables x
-        Ast "call" [Avar cmp,x,y]
-            | any (\(f,_) -> f==cmp) sqlComparisson
-            -> let (nx,vx) = expToSQL tables x
-                   (ny,vy) = expToSQL tables y
-               in if nx == ""
-                  then (ny,vx)
-                  else if ny == ""
-                       then (nx,vy)
-                       else (nx ++ " " ++ snd (head (filter (\(f,_) -> f==cmp) sqlComparisson)) ++ " " ++ ny,vx++vy)
-        Ast "call" [Avar cmp,x,y]
-            | any (\(f,_) -> f==cmp) sqlBoolean
-            -> let (nx,vx) = predToSQL tables x
-                   (ny,vy) = predToSQL tables y
-               in if nx == ""
-                  then (ny,vy)
-                  else if ny == ""
-                       then (nx,vx)
-                       else (nx ++ " " ++ snd (head (filter (\(f,_) -> f==cmp) sqlBoolean)) ++ " " ++ ny,vx++vy)
-        _ -> error ("Cannot convert to an SQL predicate: "++show e)
-      where expToSQL tables e
-                = case e of
-                    Astring s -> ("\'"++s++"\'",[])
-                    Aint n -> (show n,[])
-                    Ast "child_step" [Astring c,Avar v]
-                        -> if elem v tables
-                           then (v++"."++c,[])
-                           else ("?",[e])
-                    Ast "construction" [_,_,Ast "append" [x]]
-                        -> expToSQL tables x
-                    Ast "call" [Avar "text",x]
-                        -> expToSQL tables x
-                    _ -> ("?",[e])
-
-
--- Convert an AST to an SQL query
-makeSQL :: [Ast] -> Ast -> [Ast] -> (String,[Ast])
-makeSQL tables pred cols
-    = let tnames = [ x | Avar x <- tables ]
-          ts = combine tnames
-          cs = combine [ x | Avar x <- cols ]
-          vars (Ast n args) = concatMap vars args
-          vars (Avar v) | not (elem v tnames) = [v]
-          vars _ = []
-          combine [] = ""
-          combine [x] = x
-          combine (x:xs) = x++", "++combine xs
-      in if pred == Ast "call" [Avar "true"]
-         then (if null cs
-               then "select * from "++ts
-               else "select "++cs++" from "++ts,[])
-         else let (p,args) = predToSQL tnames pred
-              in (if null cs
-                  then "select * from "++ts++" where "++p
-                  else "select "++cs++" from "++ts++" where "++p,args)
diff --git a/XML/HXQ/DBConnect.hs b/XML/HXQ/DBConnect.hs
deleted file mode 100644
--- a/XML/HXQ/DBConnect.hs
+++ /dev/null
@@ -1,26 +0,0 @@
-{-------------------------------------------------------------------------------------
--
-- HDBC driver. Currently, Sqlite3.
-- Programmer: Leonidas Fegaras
-- Email: fegaras@cse.uta.edu
-- Web: http://lambda.uta.edu/
-- Creation: 05/30/08, last update: 05/30/08
-- 
-- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
-- This material is provided as is, with absolutely no warranty expressed or implied.
-- Any use is at your own risk. Permission is hereby granted to use or copy this program
-- for any purpose, provided the above notices are retained on all copies.
--
---------------------------------------------------------------------------------------}
-
-
-module XML.HXQ.DBConnect where
-
-
-import Database.HDBC.Sqlite3
-
-
-
--- | Connect to the relational database in filepath using the HDBC Sqlite3 driver
-connect :: FilePath -> IO Connection
-connect filepath = connectSqlite3 filepath
diff --git a/XML/HXQ/Interpreter.hs b/XML/HXQ/Interpreter.hs
deleted file mode 100644
--- a/XML/HXQ/Interpreter.hs
+++ /dev/null
@@ -1,407 +0,0 @@
-{-------------------------------------------------------------------------------------
--
-- The XQuery Interpreter
-- Programmer: Leonidas Fegaras
-- Email: fegaras@cse.uta.edu
-- Web: http://lambda.uta.edu/
-- Creation: 03/22/08, last update: 06/21/08
-- 
-- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
-- This material is provided as is, with absolutely no warranty expressed or implied.
-- Any use is at your own risk. Permission is hereby granted to use or copy this program
-- for any purpose, provided the above notices are retained on all copies.
--
---------------------------------------------------------------------------------------}
-
-
-{-# OPTIONS_GHC -fth -fglasgow-exts #-}
-
-
-module XML.HXQ.Interpreter where
-
-import Control.Monad
-import List(sortBy)
-import XMLParse(parseDocument)
-import System.Console.Readline
-import XML.HXQ.Parser
-import XML.HXQ.XTree
-import XML.HXQ.Optimizer
-import XML.HXQ.Compiler
-import Database.HDBC
-import XML.HXQ.DB
-import XML.HXQ.DBConnect
-
-
--- system functions (=, concat, etc)
-systemFunctions :: [(String,Int,[XSeq]->XSeq)]
-systemFunctions = $(iFunctions)
-
-
--- XPath step functions (child, descendant, etc)
-pathFunctions :: [(String,Tag->XTree->XSeq)]
-pathFunctions = $(pFunctions)
-
-
--- run-time bindings of FLOWR variables
-type Environment = [(String,XSeq)]
-
-
--- a user-defined function is (fname,parameters,body)
-type Functions = [(String,[String],Ast)]
-
-
-undefv1 = error "Undefined XQuery context (.)"
-undefv2 = error "Undefined position()"
-undefv3 = error "Undefined last()"
-
-
-
--- Each XPath predicate must calculate position() and last() from its input XSeq
--- if last() is used, then the evaluation is blocking (need to store the whole input XSeq)
-applyPredicates :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> XSeq
-applyPredicates [] xs _ _ _ = xs
-applyPredicates ((Aint n):preds) xs _ env fncs   -- shortcut that improves laziness
-    = applyPredicates preds [xs !! (n-1)] True env fncs
-applyPredicates (pred:preds) xs True env fncs    -- top-k like
-    | maxPosition pathPosition pred > 0
-    = applyPredicates (pred:preds) (take (maxPosition pathPosition pred) xs) False env fncs
-applyPredicates (pred:preds) xs _ env fncs
-    | containsLast pred         -- blocking: use only when last() is used in the predicate
-    = let last = length xs
-      in applyPredicates preds
-             (foldir (\x i r -> case eval pred x i last "" env fncs of
-                                  [XInt k] -> if k == i then x:r else r               -- indexing
-                                  b -> if conditionTest b then x:r else r) [] xs 1) True env fncs
-applyPredicates (pred:preds) xs _ env fncs
-    = applyPredicates preds
-          (foldir (\x i r -> case eval pred x i undefv3 "" env fncs of
-                               [XInt k] -> if k == i then x:r else r               -- indexing
-                               b -> if conditionTest b then x:r else r) [] xs 1) True env fncs
-
-
--- The XQuery interpreter
--- context: context node (XPath .)
--- position: the element position in the parent sequence (XPath position())
--- last: the length of the parent sequence (XPath last())
--- effective_axis: the XPath axis in /axis::tag(exp)
---        (eg, the effective axis of //(A | B) is "descendant_step"
--- env: contains FLOWR variable bindings
--- fncs: user-defined functions
-eval :: Ast -> XTree -> Int -> Int -> String -> Environment -> Functions -> XSeq
-eval e context position last effective_axis env fncs
-  = case e of
-      Avar "." -> [ context ]
-      Avar v -> findV v env
-      Aint n -> [ XInt n ]
-      Afloat n -> [ XFloat n ]
-      Astring s -> [ XText s ]
-      Ast "context" [v,Astring dp,body]
-          -> foldr (\x r -> (eval body x position last dp env fncs)++r)
-                   [] (eval v context position last effective_axis env fncs)
-      Ast "call" [Avar "position"] -> [XInt position]
-      Ast "call" [Avar "last"] -> [XInt last]
-      Ast "child_step" [tag, Avar "."]
-          |  effective_axis /= ""
-          -> eval (Ast effective_axis [tag, Avar "."]) context position last "" env fncs
-      Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
-          -> let ts = map (\(Avar tag) -> tag) tags
-             in foldr (\x r -> (applyPredicates predicates (descendant_any_with_tagged_children ts x) True env fncs)++r)
-                      [] (eval body context position last effective_axis env fncs)
-      Ast "step" ((Ast path_step [Astring tag,body]):predicates)
-          |  memV path_step pathFunctions
-          -> foldr (\x r -> (applyPredicates predicates ((findV path_step pathFunctions) tag x) True env fncs)++r)
-                   [] (eval body context position last effective_axis env fncs)
-      Ast "descendant_any" (body:tags)
-          -> let ts = map (\(Avar tag) -> tag) tags
-             in foldr (\x r -> (descendant_any_with_tagged_children ts x)++r)
-                      [] (eval body context position last effective_axis env fncs)
-      Ast path_step [Astring tag,body]
-          |  memV path_step pathFunctions
-          -> foldr (\x r -> ((findV path_step pathFunctions) tag x)++r)
-                   [] (eval body context position last effective_axis env fncs)
-      Ast "step" (exp:predicates)
-          -> applyPredicates predicates (eval exp context position last effective_axis env fncs) True env fncs
-      Ast "predicate" [condition,body]
-          -> applyPredicates [condition] (eval body context position last effective_axis env fncs) True env fncs
-      Ast "append" args
-          -> appendText (map (\x -> eval x context position last effective_axis env fncs) args)
-      Ast "call" ((Avar fname):args)
-          -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of
-               [(_,len,f)] -> if (length args) == len
-                              then f (map (\x -> eval x context position last effective_axis env fncs) args)
-                              else error ("Wrong number of arguments in system call: "++fname)
-               _ -> case filter (\(n,_,_) -> n == fname) fncs of
-                      (_,params,body):_ -> if (length params) == (length args)
-                                           then eval body context undefv2 undefv3 ""
-                                                    ((zipWith (\p a -> (p,eval a context position last effective_axis env fncs))
-                                                              params args)++env) fncs
-                                           else error ("Wrong number of arguments in function call: "++fname)
-                      _ -> error ("Undefined function: "++fname)
-      Ast "construction" [Astring tag,Ast "attributes" [],body]
-          -> [ XElem tag [] 0 parent_error (eval body context position last effective_axis env fncs) ]
-      Ast "construction" [tag,Ast "attributes" al,body]
-             -> let alc = map (\(Ast "pair" [a,v])
-                                     -> let ac = eval a context position last effective_axis env fncs
-                                            vc = eval v context position last effective_axis env fncs
-                                        in (qName ac,showXS vc)) al
-                    ct = eval tag context position last effective_axis env fncs
-                    bc = eval body context position last effective_axis env fncs
-                in [ XElem (qName ct) alc 0 parent_error bc ]
-      Ast "let" [Avar var,source,body]
-          -> eval body context position last effective_axis
-                  ((var,eval source context position last effective_axis env fncs):env) fncs
-      Ast "for" [Avar var,Avar "$",source,body]      -- a for-loop without an index
-          -> foldr (\a r -> (eval body a undefv2 undefv3 "" ((var,[a]):env) fncs)++r)
-                   [] (eval source context position last effective_axis env fncs)
-      Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
-          -> let p = maxPosition (Avar ivar) body
-                 ns = if p > 0              -- there is a top-k like restriction
-                      then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
-                      else source 
-             in foldir (\a i r -> (eval body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs)++r)
-                       [] (eval ns context position last effective_axis env fncs) 1
-      Ast "sortTuple" (exp:orderBys)             -- prepare each FLWOR tuple for sorting
-          -> [ XElem "" [] 0 parent_error
-                     (foldl (\r a -> r++[XElem "" [] 0 parent_error (text (eval a context position last effective_axis env fncs))])
-                                     [XElem "" [] 0 parent_error (eval exp context position last effective_axis env fncs)] orderBys) ]
-      Ast "sort" (exp:ordList)                   -- blocking
-          -> let ce = map (\(XElem _ _ _ _ xs) -> map (\(XElem _ _ _ _ ys) -> ys) xs)
-                          (eval exp context position last effective_axis env fncs)
-                 ordering = foldr (\(Avar ord) r (x:xs) (y:ys)
-                                       -> case compareXSeqs (ord == "ascending") x y of
-                                            EQ -> r xs ys
-                                            o -> o)
-                                  (\xs ys -> EQ) ordList
-             in concatMap head (sortBy (\(_:xs) (_:ys) -> ordering xs ys) ce)
-      _ -> error ("Illegal XQuery: "++(show e))
-
-
--- The monadic applyPredicates that propagates IO state
-applyPredicatesM :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> IO XSeq
-applyPredicatesM [] xs _ _ _ = return xs
-applyPredicatesM ((Aint n):preds) xs _ env fncs   -- shortcut that improves laziness
-    = applyPredicatesM preds [xs !! (n-1)] True env fncs
-applyPredicatesM (pred:preds) xs True env fncs    -- top-k like
-    | maxPosition pathPosition pred > 0
-    = applyPredicatesM (pred:preds) (take (maxPosition pathPosition pred) xs) False env fncs
-applyPredicatesM (pred:preds) xs _ env fncs
-    | containsLast pred         -- blocking: use only when last() is used in the predicate
-    = do let last = length xs
-         vs <- foldir (\x i r -> do vs <- evalM pred x i last "" env fncs
-                                    s <- r
-                                    return (if case vs of
-                                                 [XInt k] -> k == i               -- indexing
-                                                 b -> conditionTest b
-                                            then x:s else s))
-                      (return []) xs 1
-         applyPredicatesM preds vs True env fncs
-applyPredicatesM (pred:preds) xs _ env fncs
-    = do vs <- foldir (\x i r -> do vs <- evalM pred x i undefv3 "" env fncs
-                                    s <- r
-                                    return (if case vs of
-                                                 [XInt k] -> k == i               -- indexing
-                                                 b -> conditionTest b
-                                            then x:s else s))
-                      (return []) xs 1
-         applyPredicatesM preds vs True env fncs
-
-
--- The monadic XQuery interpreter; it is like eval but has plumbing to propagate IO state
-evalM :: Ast -> XTree -> Int -> Int -> String -> Environment -> Functions -> IO XSeq
-evalM e context position last effective_axis env fncs
-  = case e of
-      Avar "." -> return [ context ]
-      Avar v -> return (findV v env)
-      Aint n -> return [ XInt n ]
-      Afloat n -> return [ XFloat n ]
-      Astring s -> return [ XText s ]
-      -- for non-IO XQuery, use the regular eval
-      Ast "nonIO" [u] -> return (eval u context position last effective_axis env fncs)
-      Ast "context" [v,Astring dp,body]
-          -> do vs <- evalM v context position last effective_axis env fncs
-                foldr (\x r -> (liftM2 (++)) (evalM body x position last dp env fncs) r)
-                      (return []) vs
-      Ast "call" [Avar "position"] -> return [XInt position]
-      Ast "call" [Avar "last"] -> return [XInt last]
-      Ast "child_step" [tag, Avar "."]
-          |  effective_axis /= ""
-          -> evalM (Ast effective_axis [tag, Avar "."]) context position last "" env fncs
-      Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
-          -> do vs <- evalM body context position last effective_axis env fncs
-                let ts = map (\(Avar tag) -> tag) tags
-                foldr (\x r -> (liftM2 (++)) (applyPredicatesM predicates (descendant_any_with_tagged_children ts x) True env fncs) r)
-                      (return []) vs
-      Ast "step" ((Ast path_step [Astring tag,body]):predicates)
-          |  memV path_step pathFunctions
-          -> do vs <- evalM body context position last effective_axis env fncs
-                foldr (\x r -> (liftM2 (++)) (applyPredicatesM predicates ((findV path_step pathFunctions) tag x) True env fncs) r)
-                      (return []) vs
-      Ast "descendant_any" (body:tags)
-          -> do vs <- evalM body context position last effective_axis env fncs
-                let ts = map (\(Avar tag) -> tag) tags
-                return (foldr (\x r -> (descendant_any_with_tagged_children ts x)++r) [] vs)
-      Ast path_step [Astring tag,body]
-          |  memV path_step pathFunctions
-          -> do vs <- evalM body context position last effective_axis env fncs
-                return (foldr (\x r -> ((findV path_step pathFunctions) tag x)++r) [] vs)
-      Ast "step" (exp:predicates)
-          -> do vs <- evalM exp context position last effective_axis env fncs
-                applyPredicatesM predicates vs True env fncs
-      Ast "predicate" [condition,body]
-          -> do vs <- evalM body context position last effective_axis env fncs
-                applyPredicatesM [condition] vs True env fncs
-      Ast "executeSQL" [Avar var,args]
-          -> do as <- evalM args context position last effective_axis env fncs
-                let [XStmt stmt] = findV var env
-                executeSQL stmt as
-      Ast "call" [Avar nm,c,t,e]     -- this is the only lazy function
-          | elem nm ["if","fn:if"]
-          -> do ce <- evalM c context position last effective_axis env fncs
-                evalM (if conditionTest ce then t else e) context position last effective_axis env fncs
-      Ast "append" args
-          -> (liftM appendText) (mapM (\x -> evalM x context position last effective_axis env fncs) args)
-      Ast "call" ((Avar fname):args)        -- Note: strict function application
-          -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of
-               [(_,len,f)] -> if (length args) == len
-                              then (liftM f) (mapM (\x -> evalM x context position last effective_axis env fncs) args)
-                              else error ("Wrong number of arguments in system call: "++fname)
-               _ -> case filter (\(n,_,_) -> n == fname) fncs of
-                      (_,params,body):_ -> if (length params) == (length args)
-                                           then do vs <- mapM (\a -> evalM a context position last effective_axis env fncs) args
-                                                   evalM body context undefv2 undefv3 ""
-                                                             ((zipWith (\p a -> (p,a)) params vs)++env) fncs
-                                           else error ("Wrong number of arguments in function call: "++fname)
-                      _ -> error ("Undefined function: "++fname)
-      Ast "construction" [Astring tag,Ast "attributes" [],body]
-          -> do b <- evalM body context position last effective_axis env fncs
-                return [ XElem tag [] 0 parent_error b ]
-      Ast "construction" [tag,Ast "attributes" al,body]
-             -> do alc <- mapM (\(Ast "pair" [a,v])
-                                     -> do ac <- evalM a context position last effective_axis env fncs
-                                           vc <- evalM v context position last effective_axis env fncs
-                                           return (qName ac,showXS vc)) al
-                   ct <- evalM tag context position last effective_axis env fncs
-                   bc <- evalM body context position last effective_axis env fncs
-                   return [ XElem (qName ct) alc 0 parent_error bc ]
-      Ast "let" [Avar var,source,body]
-          -> do s <- evalM source context position last effective_axis env fncs
-                evalM body context position last effective_axis ((var,s):env) fncs
-      Ast "for" [Avar var,Avar "$",source,body]      -- a for-loop without an index
-          -> do vs <- evalM source context position last effective_axis env fncs
-                foldr (\a r -> (liftM2 (++)) (evalM body a undefv2 undefv3 "" ((var,[a]):env) fncs) r)
-                      (return []) vs
-      Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
-          -> do let p = maxPosition (Avar ivar) body
-                    ns = if p > 0              -- there is a top-k like restriction
-                            then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
-                            else source 
-                vs <- evalM ns context position last effective_axis env fncs
-                foldir (\a i r -> (liftM2 (++)) (evalM body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs) r)
-                       (return []) vs 1
-      Ast "sortTuple" (exp:orderBys)             -- prepare each FLWOR tuple for sorting
-          -> do vs <- evalM exp context position last effective_axis env fncs
-                os <- mapM (\a -> evalM a context position last effective_axis env fncs) orderBys
-                return [ XElem "" [] 0 parent_error (foldl (\r a -> r++[XElem "" [] 0 parent_error (text a)])
-                                                               [XElem "" [] 0 parent_error vs] os) ]
-      Ast "sort" (exp:ordList)                   -- blocking
-          -> do vs <- evalM exp context position last effective_axis env fncs
-                let ce = map (\(XElem _ _ _ _ xs) -> map (\(XElem _ _ _ _ ys) -> ys) xs) vs
-                    ordering = foldr (\(Avar ord) r (x:xs) (y:ys)
-                                       -> case compareXSeqs (ord == "ascending") x y of
-                                            EQ -> r xs ys
-                                            o -> o)
-                                  (\xs ys -> EQ) ordList
-                return (concatMap head (sortBy (\(_:xs) (_:ys) -> ordering xs ys) ce))
-      _ -> error ("Illegal XQuery: "++(show e))
-
-
--- evaluate from input continuously
-evalInput :: (String -> Environment -> Functions -> IO(Environment,Functions)) -> Environment -> Functions -> IO ()
-evalInput eval vs fs
-    = do let oneline prompt = do line <- readline prompt
-                                 case line of
-                                   Nothing -> return "quit"
-                                   Just t -> if t == ""
-                                             then oneline prompt
-                                             else return t
-             readlines x = do line <- oneline ": "
-                              if last line == '}'
-                                 then return (x++" "++(init line))
-                                 else if line == "quit"
-                                      then return line
-                                      else readlines (x++" "++line)
-         line <- oneline "> "
-         stmt <- if head line == '{'
-                 then if last line == '}'
-                      then return (init (tail line))
-                      else readlines (tail line)
-                 else return line
-         if stmt == "quit"
-            then putStrLn "Bye!"
-            else do addHistory stmt
-                    (nvs,nfs) <- eval (map (\c -> if c=='\"' then '\'' else c) stmt) vs fs
-                    evalInput eval nvs nfs
-
-
-xqueryE :: String -> Environment -> Functions -> (String -> IO XSeq) -> Bool -> IO (XSeq,Environment,Functions)
-xqueryE query variables functions dbmapper verbose
-    = do let asts = parse (scan query)
-             fncs = foldr (\e r -> case e of
-                                     Ast "function" ((Avar f):b:args) -> (f,map (\(Avar v) -> v) args,optimize b):r
-                                     _ -> r) functions asts
-         vars <- foldl (\r e -> case e of
-                                  Ast "variable" [Avar v,u]
-                                      -> do s <- r
-                                            uv <- evalM (optimize u) undefv1 undefv2 undefv3 "" s fncs
-                                            return ((v,uv):s)
-                                  _ -> r) (return variables) asts
-         let exprp e = case e of Ast f _ | elem f ["function","variable"] -> True; _ -> False
-             exps = concatenateAll (dropWhile exprp asts)
-             opt_exps = optimize exps
-             (ast,ns) = liftIOSources opt_exps
-         if verbose
-            then do putStrLn "Abstract Syntax Tree (AST):"
-                    putStrLn (ppAst exps)
-                    putStrLn "Optimized AST:"
-                    putStrLn (ppAst opt_exps)
-                    putStrLn "Result:"
-            else return ()
-         env <- foldr (\(n,s) r -> case s of
-                                     Avar m -> do env <- r
-                                                  return ((n,findV m env):env)
-                                     Ast "prepareSQL" [Astring sql]
-                                         -> do env <- r
-                                               t <- dbmapper sql
-                                               return ((n,t):env)
-                                     Astring file -> do doc <- readFile file
-                                                        env <- r
-                                                        return ((n,[materialize (parseDocument doc)]):env))
-                      (return []) ns
-         e <- evalM ast undefv1 undefv2 undefv3 "" (env++vars) fncs
-         return (e,vars,fncs)
-
-
--- | Evaluate the XQuery using the interpreter.
-xquery :: String -> IO XSeq
-xquery query = do (u,_,_) <- xqueryE query [] [] (\sql -> return []) False
-                  return u
-
-
--- | Read an XQuery from a file and run it using the interpreter.
-xfile :: String -> IO XSeq
-xfile file = do query <- readFile file
-                xquery query
-
-
--- | Evaluate the XQuery with database connectivity using the interpreter.
-xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq
-xqueryDB query db = do (u,_,_) <- xqueryE query [] []
-                                  (\sql -> do stmt <- prepareSQL db sql
-                                              return [XStmt stmt]) False
-                       return u
-
-
--- | Read an XQuery with database connectivity from a file and run it using the interpreter.
-xfileDB :: (IConnection conn) => String -> conn -> IO XSeq
-xfileDB file db = do query <- readFile file
-                     xqueryDB query db
diff --git a/XML/HXQ/Optimizer.hs b/XML/HXQ/Optimizer.hs
deleted file mode 100644
--- a/XML/HXQ/Optimizer.hs
+++ /dev/null
@@ -1,538 +0,0 @@
-{-------------------------------------------------------------------------------------
--
-- Preprocess abstract syntax trees, remove backward steps and optimize
-- Programmer: Leonidas Fegaras
-- Email: fegaras@cse.uta.edu
-- Web: http://lambda.uta.edu/
-- Creation: 05/01/08, last update: 06/30/08
-- 
-- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
-- This material is provided as is, with absolutely no warranty expressed or implied.
-- Any use is at your own risk. Permission is hereby granted to use or copy this program
-- for any purpose, provided the above notices are retained on all copies.
--
---------------------------------------------------------------------------------------}
-
-
-module XML.HXQ.Optimizer(optimize) where
-
---import Debug.Trace
-import System.IO.Unsafe
-import Control.Monad
-import Char(toLower)
-import Database.HDBC
-import HXML(AttList)
-import XML.HXQ.Parser
-import XML.HXQ.XTree
-import XML.HXQ.DB
-import XML.HXQ.DBConnect
-
-
-
-paths = [ "current_step", "child_step", "descendant_step", "attribute_step", "attribute_descendant_step" ]
-
-
-distinct :: Eq a => [a] -> [a]
-distinct = foldl (\r a -> if elem a r then r else r++[a]) []
-
-
-{-# NOINLINE publishXmlDoc #-}
--- get an XML document stored in a relational database
-publishXmlDoc :: FilePath -> String -> Ast
-publishXmlDoc filepath name
-    = let query = unsafePerformIO (publishWrapper filepath name)
-          [ast] = parse (scan query)
-      in ast
-    where publishWrapper filepath name
-              = do let prefix = map toLower name
-                   db <- connect filepath
-                   table <- findSchema db prefix
-                   let query = publishTable table
-                   disconnect db
-                   return query
-
-
--- collect attribute constructions inside element constructions
-collect_attributes :: Ast -> (Ast,[Ast])
-collect_attributes (Ast "attribute_construction" [attr,value])
-    = (Ast "call" [Avar "empty"],[Ast "pair" [attr,value]])
-collect_attributes (Ast "call" [Avar "concatenate",x,y])
-    = let (cx,ax) = collect_attributes x
-          (cy,ay) = collect_attributes y
-      in (Ast "call" [Avar "concatenate",cx,cy],ax++ay)
-collect_attributes (Ast "append" es)
-    = let (s,a) = foldr (\e (r,ar) -> let (cx,ax) = collect_attributes e in (cx:r,ax++ar)) ([],[]) es
-      in (Ast "append" s,a)
-collect_attributes (Ast "step" (e:es))
-    = let (ce,ae) = collect_attributes e
-      in (Ast "step" (ce:es),ae)
-collect_attributes e = (e,[])
-
-
--- does the expression contain a $var/.. ?
-parentOfVar :: Ast -> String -> Bool
-parentOfVar (Ast "step" [Ast "parent_step" [Ast "step" [Avar x]]]) var = x == var
-parentOfVar (Ast "let" [Avar v,s,_]) var | var == v = parentOfVar s var
-parentOfVar (Ast "for" [Avar v,Avar i,s,_]) var | var == v || var == i = parentOfVar s var
-parentOfVar (Ast _ args) var = or (map (\x -> parentOfVar x var) args)
-parentOfVar _ _ = False
-
-
--- replace $var/.. with $nvar
-replaceParentOfVar :: Ast -> String -> String -> Ast
-replaceParentOfVar (Ast "step" [Ast "parent_step" [Ast "step" [Avar x]]]) var nvar
-    | x == var
-    = Avar nvar
-replaceParentOfVar (Ast "let" [Avar v,s,b]) var nvar | var == v
-    = Ast "let" [Avar v,replaceParentOfVar s var nvar,b]
-replaceParentOfVar (Ast "for" [Avar v,Avar i,s,b]) var nvar | var == v || var == i
-    = Ast "for" [Avar v,Avar i,replaceParentOfVar s var nvar,b]
-replaceParentOfVar (Ast f args) var nvar
-    = Ast f (map (\x -> replaceParentOfVar x var nvar) args)
-replaceParentOfVar e _ _ = e
-
-
--- Rules to extract the parent of an XQuery expression
--- For every XQuery x and predicates p1 ... pn and for s in [tag,*,@attr]:
---    x/s[p1]...[pn]/..   ->  x[s[p1]...[pn]]
---    x//s[p1]...[pn]/..  ->  x//*[s[p1]...[pn]]
-removeParent :: Ast -> (Ast,Ast,Bool,Ast)
-removeParent (Ast "predicate" [c,x])
-         = let (nx,cond,childp,tag) = removeParent x
-           in (Ast "predicate" [c,nx],cond,childp,tag)
-removeParent (Ast "step" ((Ast "child_step" [tag,x]):preds))
-    = (Ast "step" ((Ast "child_step" [tag,Avar "."]):preds),x,True,tag)
-removeParent (Ast "step" ((Ast "descendant_step" [tag,x]):preds))
-    = (Ast "step" ((Ast "child_step" [tag,Avar "."]):preds),
-       Ast "step" [Ast "descendant_step" [Astring "*",x]],True,tag)
-removeParent (Ast "step" ((Ast "attribute_step" [tag,x]):preds))
-    = (Ast "step" ((Ast "attribute_step" [tag,Avar "."]):preds),x,False,tag)
-removeParent (Ast "step" ((Ast "descendant_attribute_step" [tag,x]):preds))
-    = (Ast "step" ((Ast "attribute_step" [tag,Avar "."]):preds),
-       Ast "step" ((Ast "descendant_step" [Astring "*",x]):preds),False,tag)
-removeParent (Ast "step" (x:xs))
-         = let (nx,cond,childp,tag) = removeParent x
-           in (Ast "step" (nx:xs),cond,childp,tag)
-removeParent e = error ("Cannot remove this parent step "++(show e))
-
-
-tagged_children :: String -> Ast -> [Tag]
-tagged_children context (Ast "step" ((Ast "child_step" [Astring tag,Avar "."]):_))
-    | context == "."
-    = [tag]
-tagged_children context (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Avar v):_)]):_))
-    | v == context
-    = [tag]
-tagged_children _ (Ast "step" ((Ast "descendant_any" _):_)) = []
-tagged_children _ (Ast "step" ((Ast step _):_))
-    | elem step paths = []
-tagged_children context (Ast _ xs) = concatMap (tagged_children context) xs
-tagged_children _ _ = []
-
-
-empty = Ast "call" [Avar "empty"]
-
-
-simplify :: Ast -> Ast
--- must be done bottom-up:    /../..
-simplify (Ast "step" [Ast "parent_step" [Ast "step" [Ast "parent_step" x]]])
-    = let nx = simplify (Ast "step" [Ast "parent_step" x])
-      in simplify (Ast "step" [Ast "parent_step" [nx]])
--- get rid of a parent step
-simplify (Ast "step" [Ast "parent_step" [x]])
-    = let (cond,nx,_,_) = removeParent x
-      in Ast "predicate" [simplify cond,simplify nx]
--- remove $var/.. in a let-FLWOR
-simplify (Ast "let" [Avar var,source,body])
-    | parentOfVar body var
-    = let (cond,nx,childp,tag) = removeParent source
-      in simplify (Ast "let" [Avar (var++"_parent"),Ast "predicate" [cond,nx],
-                              Ast "let" [Avar var,
-                                         Ast "step" [ Ast (if childp
-                                                           then "child_step"
-                                                           else "attribute_step")
-                                                      [tag,Avar (var++"_parent")] ],
-                                         replaceParentOfVar body var (var++"_parent")]])
--- remove $var/.. from a for-FLWOR
-simplify (Ast "for" [Avar var,Avar "$",source,body])
-    | parentOfVar body var
-    = let (cond,nx,childp,tag) = removeParent source
-      in simplify (Ast "for" [Avar (var++"_parent"),Avar "$",Ast "predicate" [cond,nx],
-                              Ast "for" [Avar var,Avar "$",
-                                         Ast "step" [ Ast (if childp
-                                                           then "child_step"
-                                                           else "attribute_step")
-                                                      [tag,Avar (var++"_parent")] ],
-                                         replaceParentOfVar body var (var++"_parent")]])
--- pull out attributes from a general element construction
-simplify (Ast "element_construction" [tag,Ast "attributes" as,content])
-    = let (nc,attrs) = collect_attributes content
-      in simplify (Ast "construction" [tag,Ast "attributes" (as++attrs),nc])
--- if //* collect all children tagnames to use descendant_any_with_tagged_children
-simplify (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)],body])
-    | not (null ((tagged_children var body))) || any (not . null . (tagged_children ".")) preds
-    = let ctags = distinct ((tagged_children var body)++(concatMap (tagged_children ".") preds))
-          tags = map Avar ctags
-      in simplify (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_any" (path:tags)):preds)],body])
-simplify (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)]):preds2))
-    = let ctags = distinct(tag:(concatMap (tagged_children ".") preds))
-          tags = map Avar ctags
-      in simplify (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_any" (path:tags)):preds)]):preds2))
-simplify (Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds))
-    | any (not . null . (tagged_children ".")) preds
-    = let ctags = distinct (concatMap (tagged_children ".") preds)
-          tags = map Avar ctags
-      in simplify (Ast "step" ((Ast "descendant_any" (path:tags)):preds))
--- expand the wrapper of a stored document
-simplify (Ast "call" [Avar "publish",Astring dbpath,Astring name])
-    = simplify (publishXmlDoc dbpath name)
--- default
-simplify (Ast n args) = Ast n (map simplify args)
-simplify e = e
-
-
-taggedElement :: [Ast] -> String -> Maybe [Ast]
-taggedElement (e@(Ast "construction" [Astring ctag,_,x]):xs) tag
-    | ctag == tag || tag == "*"
-    = case taggedElement xs tag of
-        Nothing -> Nothing
-        Just s -> Just (e:s)
-taggedElement ((Ast "construction" [_,_,_]):xs) tag
-    = taggedElement xs tag
-taggedElement ((Ast "call" [Avar "concatenate",x,y]):xs) tag
-    = case (taggedElement (x:xs) tag,taggedElement (y:xs) tag) of
-        (Just tx,Just ty) -> Just (tx++ty)
-        _ -> Nothing
-taggedElement ((Astring _):xs) tag
-    = taggedElement xs tag
-taggedElement ((Aint _):xs) tag
-    = taggedElement xs tag
-taggedElement (e:xs) tag = Nothing
-taggedElement [] _ = Just []
-
-
-findAttr :: String -> [Ast] -> Ast
-findAttr tag ((Ast "pair" [Astring a,v]):_) | a==tag || tag=="*" = v
-findAttr tag (_:xs) = findAttr tag xs
-findAttr _ [] = empty
-
-
-andAll :: [Ast] -> Ast
-andAll [x] = x
-andAll (x:xs) = foldl (\a r -> call "and" [a,r]) x xs
-
-
-occursContext :: Ast -> Int
-occursContext e
-    = case e of
-        Avar "." -> 1
-        Ast "let" _ -> 0
-        Ast "for" _ -> 0
-        Ast "call" [Avar "SQL",s,f,w]
-            -> occursContext w
-        Ast "descendant_any" (x:tags)
-            -> occursContext x
-        Ast step [tag,x]
-            | elem step paths
-            -> occursContext x
-        Ast n xs -> sum (map occursContext xs)
-        _ -> 0
-
-
-substContext :: Ast -> Ast -> Ast
-substContext e b
-    = case b of
-        Avar "." -> e
-        Ast "let" _ -> b
-        Ast "for" _ -> b
-        Ast "call" [Avar "SQL",s,f,w]
-            -> Ast "call" [Avar "SQL",s,f,substContext e w]
-        Ast "descendant_any" (x:tags)
-            -> Ast "descendant_any" ((substContext e x):tags)
-        Ast step [tag,x]
-            | elem step paths
-            -> Ast step [tag,substContext e x]
-        Ast n xs -> Ast n (map (substContext e) xs)
-        _ -> b
-
-
-occurs :: String -> Ast -> Int
-occurs v e
-    = case e of
-        Avar w | v==w -> 1
-        Ast "let" [Avar w,_,_] | v==w -> 0
-        Ast "for" [Avar w,Avar i,_,_] | v==w || v==i -> 0
-        Ast "call" [Avar "SQL",s,f,w]
-            -> occurs v w
-        Ast n xs -> sum (map (occurs v) xs)
-        _ -> 0
-
-
-subst :: String -> Ast -> Ast -> Ast
-subst v e b
-    = case b of
-        Avar w | v==w -> e
-        Ast "let" [Avar w,_,_] | v==w -> b
-        Ast "for" [Avar w,Avar i,_,_] | v==w || v==i -> b
-        Ast "call" [Avar "SQL",s,f,w]
-            -> Ast "call" [Avar "SQL",s,f,subst v e w]
-        Ast n xs -> Ast n (map (subst v e) xs)
-        _ -> b
-
-
-dependsOnPosition :: Bool -> Ast -> Bool
-dependsOnPosition contextp e
-    = case e of
-        Avar "." -> contextp
-        Ast "call" [Avar "position"] -> True
-        Ast "call" [Avar "last"] -> True
-        Ast "call" ((Avar "step"):x:_)
-            -> dependsOnPosition contextp x
-        Ast _ xs -> any (dependsOnPosition contextp) xs
-        _ -> False
-
-
-wellFormedPredicate :: Bool -> Ast -> Bool
-wellFormedPredicate contextp e
-    = case e of
-        Ast "call" ((Avar "step"):x:_)
-            -> not (dependsOnPosition contextp x)
-        Ast step xs
-            | elem step paths || step == "descendant_any"
-            -> not (any (dependsOnPosition contextp) xs)
-        Ast "construction" xs
-            -> not (any (dependsOnPosition contextp) xs)
-        Ast "call" [Avar "not",x]
-            -> not (dependsOnPosition contextp x)
-        Ast "call" [Avar cmp,x,y]
-            | any (\(f,_) -> f==cmp) (sqlComparisson++sqlBoolean)
-            -> not (dependsOnPosition contextp x)
-               && not (dependsOnPosition contextp y)
-        _ -> False
-
-
-splitSqlPredicate :: [String] -> Ast -> Maybe(Ast,Ast)
-splitSqlPredicate tables (Ast "call" [Avar "and",p1,p2])
-    = case (splitSqlPredicate tables p1,splitSqlPredicate tables p2) of
-        (Nothing,Nothing) -> Nothing
-        (Nothing,Just(pp1,pp2)) -> Just(pp1,Ast "call" [Avar "and",p1,pp2])
-        (Just(pp1,pp2),Nothing) -> Just(pp1,Ast "call" [Avar "and",p2,pp2])
-splitSqlPredicate tables pred
-    | sqlPredicate tables pred
-    = Just(pred,Ast "call" [Avar "true"])
-splitSqlPredicate tables pred = Nothing
-
-
--- Normalization
-normalize :: Ast -> Bool -> Int -> (Ast,Bool,Int)
-normalize exp changed count
-    = case exp of
-        Ast "step" [x]
-            -> normalize x True count
-        Ast "step" (x:(Ast "call" [Avar "true"]):xs)
-            -> norm (Ast "step" (x:xs))
-        Ast "step" (x:(Ast "call" [Avar "false"]):xs)
-            -> (empty,True,count)
-        Ast "for" [v,i,Ast "call" [Avar "empty"],b]
-            -> (empty,True,count)
-        Ast "for" [v,i,s,Ast "call" [Avar "empty"]]
-            -> (empty,True,count)
-        Ast "descendant_any" ((Astring _):_)
-            -> (empty,True,count)
-        Ast "descendant_any" ((Aint _):_)
-            -> (empty,True,count)
-        Ast "descendant_any" ((Afloat _):_)
-            -> (empty,True,count)
-        Ast "descendant_any" ((Ast "call" [Avar "text",_]):_)
-            -> (empty,True,count)
-        Ast "descendant_any" ((Ast "call" [Avar "empty"]):_)
-            -> (empty,True,count)
-        Ast step [_,Astring _]
-            | elem step paths
-            -> (empty,True,count)
-        Ast step [_,Aint _]
-            | elem step paths
-            -> (empty,True,count)
-        Ast step [_,Afloat _]
-            | elem step paths
-            -> (empty,True,count)
-        Ast step [_,Ast "call" [Avar "text",_]]
-            | elem step paths
-            -> (empty,True,count)
-        Ast step [_,Ast "call" [Avar "empty"]]
-            | elem step paths
-            -> (empty,True,count)
-        Ast "call" [Avar "and",Ast "call" [Avar "true"],x]
-            -> norm x
-        Ast "call" [Avar "and",x,Ast "call" [Avar "true"]]
-            -> norm x
-        -- (x,())  ->  x
-        Ast "call" [Avar "concatenate",x,Ast "call" [Avar "empty"]]
-            -> norm x
-        -- ((),x)  ->  x
-        Ast "call" [Avar "concatenate",Ast "call" [Avar "empty"],x]
-            -> norm x
-        -- for $v1 in (for $v2 in s2 return b2) return b1  -->  for $v2 in s2, for $v1 in b2 return b1
-        Ast "for" [v1,i1,Ast "for" [v2,i2,s2,b2],b1]
-            -> norm (Ast "for" [v2,i2,s2,Ast "for" [v1,i1,b2,b1]])
-        -- (for $v in s return b)/tag  -->  for $v in s return b/tag  -->  
-        Ast "descendant_any" ((Ast "for" [v,i,s,b]):tags)
-            -> norm (Ast "for" [v,i,s,Ast "descendant_any" (b:tags)])
-        Ast step [tag,Ast "for" [v,i,s,b]]
-            | elem step paths
-            -> norm (Ast "for" [v,i,s,Ast step [tag,b]])
-        -- (x,y)/tag  -->  (x/tag,y/tag)
-        Ast "descendant_any" ((Ast "call" [Avar "concatenate",x,y]):tags)
-            -> norm (Ast "call" [Avar "concatenate",Ast "descendant_any" (x:tags),Ast "descendant_any" (y:tags)])
-        Ast step [tag,Ast "call" [Avar "concatenate",x,y]]
-            | elem step paths
-            -> norm (Ast "call" [Avar "concatenate",Ast step [tag,x],Ast step [tag,y]])
-        -- for $v in (x,y) return b  -->  (for $v in x return b,for $v in y return b)
-        Ast "for" [v,i@(Avar "$"),Ast "call" [Avar "concatenate",x,y],b]
-            -> norm (Ast "call" [Avar "concatenate",Ast "for" [v,i,x,b],Ast "for" [v,i,y,b]])
-        -- for $v in <a>...</a> return b  -->  b[$v/(<a>...</a>)]
-        Ast "for" [Avar v,Avar i,e,b]
-            | case e of Ast "construction" _ -> True; Ast _ _ -> False; _ -> True
-            -> norm (if i == "$"
-                     then subst v e b
-                     else subst v e (subst i (Aint 1) b))
-        --Ast "for" [Avar v,Avar i,Ast "predicate" [pred,e],b]
-        --    -> norm (Ast "for" [Avar v,Avar i,e,Ast "predicate" [pred,b]])
-        Ast "for" [Avar v,Avar i,Ast "predicate" [pred,e],b]
-            | occurs v pred == 0 && occurs i pred == 0 && occursContext pred == 0
-            -> norm (Ast "predicate" [pred,Ast "for" [Avar v,Avar i,e,b]])
-        -- unfold linear let
-        Ast "let" [Avar v,e,b]
-            | occurs v b < 2
-            -> norm (subst v e b)
-        -- (if c then t else e)/A  -->  if c then t/A else e/A
-        Ast "descendant_any" ((Ast "predicate" [c,e]):tags)
-            | wellFormedPredicate True c
-            -> norm (Ast "predicate" [c,Ast "descendant_any" (e:tags)])
-        Ast step [tag,Ast "predicate" [c,e]]
-            | elem step paths && wellFormedPredicate True c
-            -> norm (Ast "predicate" [c,Ast step [tag,e]])
-        -- if p doesn't depend on context:  (e[p])/A  -->  (e/A)[p]
-        Ast "descendant_any" ((Ast "step" (x:xs@(_:_))):tags)
-            | all (wellFormedPredicate True) xs
-            -> norm (Ast "step" ((Ast "descendant_any" (x:tags)):xs))
-        Ast step [tag,Ast "step" (x:xs@(_:_))]
-            | elem step paths && all (wellFormedPredicate True) xs
-            -> norm (Ast "step" ((Ast step [tag,x]):xs))
-        -- normalize predicate
-        Ast "predicate" [pred,x]
-            | occursContext pred > 0
-            -> let v = "x"++show count
-               in normalize (Ast "for" [Avar v,Avar "$",x,Ast "predicate" [substContext (Avar v) pred,Avar v]]) True (count+1)
-        Ast "step" [x,pred]
-            | occursContext pred > 0
-            -> let v = "x"++show count
-               in normalize (Ast "for" [Avar v,Avar "$",x,Ast "predicate" [substContext (Avar v) pred,Avar v]]) True (count+1)
-        Ast "predicate" [p1,Ast "predicate" [p2,e]]
-            -> norm (Ast "predicate" [Ast "call" [Avar "and",p1,p2],e])
-        Ast "predicate" [Ast "call"[Avar "false"],x]
-            -> (empty,True,count)
-        Ast "predicate" [Ast "call"[Avar "true"],x]
-            -> (x,True,count)
-        Ast "predicate" [x,Ast "call"[Avar "empty"]]
-            -> (empty,True,count)
-        Ast "step" ((Ast "call" [Avar "empty"]):xs)
-            -> (empty,True,count)
-        -- promote well-formed predicates; but note:  (x,y)[1] <> (x[1],y[1])
-        Ast "step" ((Ast "call" [Avar "concatenate",x,y]):xs)
-            | all (wellFormedPredicate False) xs
-            -> norm (Ast "call" [Avar "concatenate",Ast "step" (x:xs),Ast "step" (y:xs)])
-        Ast "predicate" [pred,Ast "for" [v,i,s,b]]
-            | wellFormedPredicate False pred
-            -> norm (Ast "for" [v,i,s,Ast "predicate" [pred,b]])
-        Ast "step" ((Ast "for" [v,i,s,b]):xs)
-            | all (wellFormedPredicate False) xs
-            -> norm (Ast "for" [v,i,s,Ast "predicate" [andAll xs,b]])
-        Ast "step" (e@(Ast "construction" [_,_,_]):xs)
-            -> if sum (map occursContext xs) > 0
-               then norm (Ast "predicate" [andAll (map (substContext e) xs),e])
-               else let (r,b,c) = foldr (\a (r,b,c) -> let (x,s,i) = normalize a b c in (x:r,s,i))
-                                        ([],changed,count) (e:xs)
-                    in (Ast "step" r,b,c)
-        Ast "call" [Avar "=",x,y]
-            | x == empty || y == empty
-            -> (Ast "call"[Avar "true"],True,count)
-        -- (<ctag>...<tag>...</tag>...</ctag>)/tag  -->  ...<tag>...</tag>...
-        Ast "child_step" [Astring tag,Ast "construction" [_,_,Ast "append" x]]
-            | taggedElement x tag /= Nothing
-            -> case taggedElement x tag of
-                 Just [] -> (empty,True,count)
-                 Just s -> norm (concatenateAll s)
-        Ast "child_step" [Astring tag,Ast "construction" [_,_,Ast "append" x]]
-            -> norm (Ast "current_step" [Astring tag,concatenateAll x])
-        Ast "current_step" [Astring tag1,e@(Ast "construction" [Astring tag2,_,Ast "append" x])]
-            -> if tag1 == tag2 || tag1 == "*"
-               then norm e
-               else (empty,True,count)
-        -- (<tag>x</tag>)//tag  --> (x,x//tag)
-        Ast "descendant_any" (z@(Ast "construction" [Astring ctag,_,Ast "append" x]):tags)
-            -> norm (Ast "call" [Avar "concatenate",z,Ast "descendant_any" ((concatenateAll x):tags)])
-        Ast "descendant_step" [Astring tag,z@(Ast "construction" [Astring ctag,_,Ast "append" x])]
-            -> norm (if tag == ctag || tag == "*"
-                     then Ast "call" [Avar "concatenate",z,Ast "descendant_step" [Astring tag,concatenateAll x]]
-                     else Ast "descendant_step" [Astring tag,concatenateAll x])
-        -- (<tag A=s>x</tag>)/@A  --> s
-        Ast "attribute_step" [Astring tag,Ast "construction" [ctag,Ast "attributes" as,x]]
-            -> (findAttr tag as,True,count)
-        -- (<tag A=s>x</tag>)//@A  --> (s,x//@A)
-        Ast "attribute_descendant_step" [Astring tag,Ast "construction" [ctag,Ast "attributes" as,Ast "append" x]]
-            -> norm (Ast "call" [Avar "concatenate",findAttr tag as,
-                                 Ast "attribute_descendant_step" [Astring tag,concatenateAll x]])
-        -- SQL folding
-        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],
-                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],b]]
-            | occurs v1 b == 0
-            -> norm (Ast "for" [Avar v2,Avar "$",
-                                Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):(s1++s2)),
-                                            Ast "call" ((Avar "from"):(f1++f2)),Ast "call" [Avar "and",pred1,pred2]],
-                                b])
-        Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "from"):tables),pred1],
-                   Ast "predicate" [pred2,x]]
-            | splitSqlPredicate [ v | Avar v <- tables ] pred2 /= Nothing
-            -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- tables ] pred2
-               in norm (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),
-                                                               Ast "call" ((Avar "from"):tables),Ast "call" [Avar "and",pred1,pred3]],
-                                   Ast "predicate" [pred4,x]])
-        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],
-                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],
-                              Ast "predicate" [predd,b]]]
-            | occurs v1 b == 0 && splitSqlPredicate [ v | Avar v <- f1 ] predd /= Nothing
-            -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- f1 ] predd
-               in norm (Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),
-                                                                Ast "call" ((Avar "from"):f1),Ast "call" [Avar "and",pred1,pred3]],
-                                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],
-                                              Ast "predicate" [pred4,b]]])
-        -- default
-        Ast n args
-            -> let (r,b,c) = foldr (\a (r,b,c) -> let (x,s,i) = normalize a b c in (x:r,s,i))
-                                   ([],changed,count) args
-               in (Ast n r,b,c)
-        _ -> (exp,changed,count)
-    where norm e = normalize e True count
-          --tnorm e = trace ("*** "++show exp++"\n--> "++ppAst e) (normalize e True count)
-
-
-foldSQL :: Ast -> Ast
-foldSQL e
-    = case e of
-        Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):cols),Ast "call" ((Avar "from"):tables),pred]
-            -> let (sql,args) = makeSQL tables pred cols
-               in Ast "call" [Avar "sql",Astring sql,concatenateAll args]
-        Ast n args -> Ast n (map foldSQL args)
-        _ -> e
-
-
-optimizeLoop :: Ast -> Int -> (Ast,Int)
-optimizeLoop e c = let (ne,b,c') = normalize e False c
-                   in if b
-                      then optimizeLoop ne c'
-                      else (ne,c)
-
-
-optimize :: Ast -> Ast
-optimize e = foldSQL (fst (optimizeLoop (simplify e) 0))
diff --git a/XML/HXQ/Parser.hs b/XML/HXQ/Parser.hs
deleted file mode 100644
--- a/XML/HXQ/Parser.hs
+++ /dev/null
@@ -1,2153 +0,0 @@
-{-# OPTIONS -fglasgow-exts -cpp #-}
-module XML.HXQ.Parser where
-import Char
-#if __GLASGOW_HASKELL__ >= 503
-import Data.Array
-#else
-import Array
-#endif
-#if __GLASGOW_HASKELL__ >= 503
-import GHC.Exts
-#else
-import GlaExts
-#endif
-
--- parser produced by Happy Version 1.17
-
-newtype HappyAbsSyn  = HappyAbsSyn HappyAny
-#if __GLASGOW_HASKELL__ >= 607
-type HappyAny = GHC.Exts.Any
-#else
-type HappyAny = forall a . a
-#endif
-happyIn4 :: ([ Ast ]) -> (HappyAbsSyn )
-happyIn4 x = unsafeCoerce# x
-{-# INLINE happyIn4 #-}
-happyOut4 :: (HappyAbsSyn ) -> ([ Ast ])
-happyOut4 x = unsafeCoerce# x
-{-# INLINE happyOut4 #-}
-happyIn5 :: (Ast) -> (HappyAbsSyn )
-happyIn5 x = unsafeCoerce# x
-{-# INLINE happyIn5 #-}
-happyOut5 :: (HappyAbsSyn ) -> (Ast)
-happyOut5 x = unsafeCoerce# x
-{-# INLINE happyOut5 #-}
-happyIn6 :: ([ Ast ]) -> (HappyAbsSyn )
-happyIn6 x = unsafeCoerce# x
-{-# INLINE happyIn6 #-}
-happyOut6 :: (HappyAbsSyn ) -> ([ Ast ])
-happyOut6 x = unsafeCoerce# x
-{-# INLINE happyOut6 #-}
-happyIn7 :: (Ast) -> (HappyAbsSyn )
-happyIn7 x = unsafeCoerce# x
-{-# INLINE happyIn7 #-}
-happyOut7 :: (HappyAbsSyn ) -> (Ast)
-happyOut7 x = unsafeCoerce# x
-{-# INLINE happyOut7 #-}
-happyIn8 :: (Ast) -> (HappyAbsSyn )
-happyIn8 x = unsafeCoerce# x
-{-# INLINE happyIn8 #-}
-happyOut8 :: (HappyAbsSyn ) -> (Ast)
-happyOut8 x = unsafeCoerce# x
-{-# INLINE happyOut8 #-}
-happyIn9 :: ([ Ast ]) -> (HappyAbsSyn )
-happyIn9 x = unsafeCoerce# x
-{-# INLINE happyIn9 #-}
-happyOut9 :: (HappyAbsSyn ) -> ([ Ast ])
-happyOut9 x = unsafeCoerce# x
-{-# INLINE happyOut9 #-}
-happyIn10 :: (Ast -> Ast) -> (HappyAbsSyn )
-happyIn10 x = unsafeCoerce# x
-{-# INLINE happyIn10 #-}
-happyOut10 :: (HappyAbsSyn ) -> (Ast -> Ast)
-happyOut10 x = unsafeCoerce# x
-{-# INLINE happyOut10 #-}
-happyIn11 :: (Ast -> Ast) -> (HappyAbsSyn )
-happyIn11 x = unsafeCoerce# x
-{-# INLINE happyIn11 #-}
-happyOut11 :: (HappyAbsSyn ) -> (Ast -> Ast)
-happyOut11 x = unsafeCoerce# x
-{-# INLINE happyOut11 #-}
-happyIn12 :: (Ast -> Ast) -> (HappyAbsSyn )
-happyIn12 x = unsafeCoerce# x
-{-# INLINE happyIn12 #-}
-happyOut12 :: (HappyAbsSyn ) -> (Ast -> Ast)
-happyOut12 x = unsafeCoerce# x
-{-# INLINE happyOut12 #-}
-happyIn13 :: (Ast -> Ast) -> (HappyAbsSyn )
-happyIn13 x = unsafeCoerce# x
-{-# INLINE happyIn13 #-}
-happyOut13 :: (HappyAbsSyn ) -> (Ast -> Ast)
-happyOut13 x = unsafeCoerce# x
-{-# INLINE happyOut13 #-}
-happyIn14 :: (( Ast -> Ast, Ast -> Ast )) -> (HappyAbsSyn )
-happyIn14 x = unsafeCoerce# x
-{-# INLINE happyIn14 #-}
-happyOut14 :: (HappyAbsSyn ) -> (( Ast -> Ast, Ast -> Ast ))
-happyOut14 x = unsafeCoerce# x
-{-# INLINE happyOut14 #-}
-happyIn15 :: (( [ Ast ], [ Ast ] )) -> (HappyAbsSyn )
-happyIn15 x = unsafeCoerce# x
-{-# INLINE happyIn15 #-}
-happyOut15 :: (HappyAbsSyn ) -> (( [ Ast ], [ Ast ] ))
-happyOut15 x = unsafeCoerce# x
-{-# INLINE happyOut15 #-}
-happyIn16 :: (Ast) -> (HappyAbsSyn )
-happyIn16 x = unsafeCoerce# x
-{-# INLINE happyIn16 #-}
-happyOut16 :: (HappyAbsSyn ) -> (Ast)
-happyOut16 x = unsafeCoerce# x
-{-# INLINE happyOut16 #-}
-happyIn17 :: (Ast) -> (HappyAbsSyn )
-happyIn17 x = unsafeCoerce# x
-{-# INLINE happyIn17 #-}
-happyOut17 :: (HappyAbsSyn ) -> (Ast)
-happyOut17 x = unsafeCoerce# x
-{-# INLINE happyOut17 #-}
-happyIn18 :: (Ast) -> (HappyAbsSyn )
-happyIn18 x = unsafeCoerce# x
-{-# INLINE happyIn18 #-}
-happyOut18 :: (HappyAbsSyn ) -> (Ast)
-happyOut18 x = unsafeCoerce# x
-{-# INLINE happyOut18 #-}
-happyIn19 :: ([ Ast ]) -> (HappyAbsSyn )
-happyIn19 x = unsafeCoerce# x
-{-# INLINE happyIn19 #-}
-happyOut19 :: (HappyAbsSyn ) -> ([ Ast ])
-happyOut19 x = unsafeCoerce# x
-{-# INLINE happyOut19 #-}
-happyIn20 :: ([ Ast ]) -> (HappyAbsSyn )
-happyIn20 x = unsafeCoerce# x
-{-# INLINE happyIn20 #-}
-happyOut20 :: (HappyAbsSyn ) -> ([ Ast ])
-happyOut20 x = unsafeCoerce# x
-{-# INLINE happyOut20 #-}
-happyIn21 :: (Ast) -> (HappyAbsSyn )
-happyIn21 x = unsafeCoerce# x
-{-# INLINE happyIn21 #-}
-happyOut21 :: (HappyAbsSyn ) -> (Ast)
-happyOut21 x = unsafeCoerce# x
-{-# INLINE happyOut21 #-}
-happyIn22 :: ([Ast]) -> (HappyAbsSyn )
-happyIn22 x = unsafeCoerce# x
-{-# INLINE happyIn22 #-}
-happyOut22 :: (HappyAbsSyn ) -> ([Ast])
-happyOut22 x = unsafeCoerce# x
-{-# INLINE happyOut22 #-}
-happyIn23 :: ([ Ast ]) -> (HappyAbsSyn )
-happyIn23 x = unsafeCoerce# x
-{-# INLINE happyIn23 #-}
-happyOut23 :: (HappyAbsSyn ) -> ([ Ast ])
-happyOut23 x = unsafeCoerce# x
-{-# INLINE happyOut23 #-}
-happyIn24 :: (Ast) -> (HappyAbsSyn )
-happyIn24 x = unsafeCoerce# x
-{-# INLINE happyIn24 #-}
-happyOut24 :: (HappyAbsSyn ) -> (Ast)
-happyOut24 x = unsafeCoerce# x
-{-# INLINE happyOut24 #-}
-happyIn25 :: (Ast -> Ast) -> (HappyAbsSyn )
-happyIn25 x = unsafeCoerce# x
-{-# INLINE happyIn25 #-}
-happyOut25 :: (HappyAbsSyn ) -> (Ast -> Ast)
-happyOut25 x = unsafeCoerce# x
-{-# INLINE happyOut25 #-}
-happyIn26 :: (Ast -> Ast) -> (HappyAbsSyn )
-happyIn26 x = unsafeCoerce# x
-{-# INLINE happyIn26 #-}
-happyOut26 :: (HappyAbsSyn ) -> (Ast -> Ast)
-happyOut26 x = unsafeCoerce# x
-{-# INLINE happyOut26 #-}
-happyIn27 :: (String -> Ast -> [ Ast ]) -> (HappyAbsSyn )
-happyIn27 x = unsafeCoerce# x
-{-# INLINE happyIn27 #-}
-happyOut27 :: (HappyAbsSyn ) -> (String -> Ast -> [ Ast ])
-happyOut27 x = unsafeCoerce# x
-{-# INLINE happyOut27 #-}
-happyIn28 :: (String -> Ast -> Ast) -> (HappyAbsSyn )
-happyIn28 x = unsafeCoerce# x
-{-# INLINE happyIn28 #-}
-happyOut28 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)
-happyOut28 x = unsafeCoerce# x
-{-# INLINE happyOut28 #-}
-happyIn29 :: (String -> Ast -> Ast) -> (HappyAbsSyn )
-happyIn29 x = unsafeCoerce# x
-{-# INLINE happyIn29 #-}
-happyOut29 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)
-happyOut29 x = unsafeCoerce# x
-{-# INLINE happyOut29 #-}
-happyInTok :: Token -> (HappyAbsSyn )
-happyInTok x = unsafeCoerce# x
-{-# INLINE happyInTok #-}
-happyOutTok :: (HappyAbsSyn ) -> Token
-happyOutTok x = unsafeCoerce# x
-{-# INLINE happyOutTok #-}
-
-
-happyActOffsets :: HappyAddr
-happyActOffsets = HappyA# "\xce\x00\xce\x00\x00\x00\x00\x00\x47\x02\x9c\x00\x00\x00\x00\x00\x40\x00\x00\x00\x06\x00\x00\x00\xfd\xff\x00\x00\x00\x00\x7e\x01\x7e\x01\x13\x01\x89\x00\x13\x01\x13\x01\x13\x01\x00\x00\x68\x01\x13\x01\x5f\x01\x5f\x01\x1c\x00\x17\x00\x63\x00\x97\x01\xa9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xff\x5c\x01\x00\x00\x44\x00\x64\x01\x5b\x01\xff\xff\xfd\xff\x43\x01\x13\x01\x71\x01\x41\x01\x13\x01\x6f\x01\x4c\x01\x4b\x01\xec\xff\x2a\x01\x00\x00\x3c\x01\x00\x00\x00\x00\x47\x02\x64\x00\x10\x00\x00\x00\x73\x01\x3a\x00\x38\x00\x1b\x01\x00\x00\x13\x01\x28\x00\x13\x01\x00\x00\x16\x00\x00\x00\x23\x01\x0f\x01\x0f\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x63\x02\x63\x02\x63\x02\x95\x02\x63\x02\x7c\x02\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x08\x01\x08\x01\x56\x08\x47\x02\x24\x01\x22\x01\x4e\x01\x14\x01\x00\x00\xfa\xff\x13\x01\x01\x00\xfb\xff\x12\x01\x00\x00\x00\x00\x59\x00\x3a\x01\x63\x00\x62\x00\x00\x00\xb7\x01\x00\x00\xf9\x00\x13\x01\x13\x01\x13\x01\x00\x00\x13\x01\x00\x00\x00\x01\x25\x01\x13\x01\xf4\x00\xf4\x00\x13\x01\x13\x01\x2b\x02\x29\x01\x13\x01\x0e\x02\x27\x01\xef\x00\x0e\x00\x00\x00\x03\x01\x1e\x01\xe3\x00\x00\x00\x0c\x00\x13\x01\x00\x00\x00\x00\x1a\x01\x57\x00\x00\x00\x19\x01\x51\x00\x47\x02\xf0\x00\xe6\x00\x47\x02\xfc\xff\xfb\x00\x47\x02\x96\x01\x47\x02\x47\x02\xe8\xff\x00\x00\xf8\x00\x63\x00\xf8\x00\x00\x00\xf5\x00\x4f\x00\x00\x00\x13\x01\xc2\x00\x00\x00\x00\x00\x13\x01\x13\x01\x47\x02\x4d\x01\xdb\x00\xd9\x00\x49\x00\x00\x00\x00\x00\xe7\x00\x13\x01\xa1\x00\x13\x01\xfc\xff\x00\x00\x13\x01\x13\x01\x00\x00\x13\x01\x00\x00\x13\x01\x47\x02\x08\x00\x00\x00\xcf\x00\x13\x01\xca\x00\x85\x00\x24\x00\x12\x00\x47\x02\x47\x02\x00\x00\x47\x02\x97\x00\x47\x02\x00\x00\x00\x00\x13\x01\x00\x00\x00\x00\x00\x00\x4d\x01\x13\x01\x00\x00\x00\x00\x00\x00\x13\x01\xf1\x01\x00\x00\xd4\x01\x47\x02\x00\x00\x00\x00\x00\x00"#
-
-happyGotoOffsets :: HappyAddr
-happyGotoOffsets = HappyA# "\xa7\x00\x31\x01\x00\x00\x00\x00\x00\x00\xb1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x01\x00\x00\x00\x00\xd8\x00\xd1\x00\x4a\x08\x9e\x03\x87\x03\x33\x08\x1c\x08\x00\x00\x00\x00\x05\x08\xc1\x00\x7f\x00\x00\x00\x00\x00\xf3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec\x00\x00\x00\xb4\x00\x70\x03\xdf\x00\x00\x00\xee\x07\x00\x00\x00\x00\xd7\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\xc0\x07\xd3\x00\x59\x03\x00\x00\x0d\x00\x00\x00\x9f\x00\x8e\x00\x71\x00\xa9\x07\x92\x07\x7b\x07\x64\x07\x4d\x07\x36\x07\x1f\x07\x08\x07\xf1\x06\xda\x06\xc3\x06\xac\x06\x95\x06\x7e\x06\x67\x06\x50\x06\x39\x06\x22\x06\x0b\x06\xf4\x05\xdd\x05\xc6\x05\xaf\x05\x98\x05\x81\x05\x6a\x05\x53\x05\x3c\x05\x25\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x00\x42\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x00\xc9\x00\x00\x00\x00\x00\x00\x00\x9b\x00\x0e\x05\xf7\x04\xe0\x04\x00\x00\xc9\x04\x00\x00\x00\x00\x00\x00\xb2\x04\x93\x00\x77\x00\x9b\x04\x2b\x03\x00\x00\x00\x00\x14\x03\x00\x00\x00\x00\xf5\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x84\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\x02\x00\x00\x00\x00\x00\x00\xe6\x02\x6d\x04\x00\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x04\x20\x00\x3f\x04\x4d\x00\x00\x00\x28\x04\x11\x04\x00\x00\xcf\x02\x00\x00\xb8\x02\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\x03\x00\x00\x00\x00\x00\x00\x1f\x00\xcc\x03\x00\x00\x00\x00\x00\x00\xb5\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
-
-happyDefActions :: HappyAddr
-happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x8b\xff\xfa\xff\xbd\xff\xed\xff\xee\xff\x00\x00\xcd\xff\xa2\xff\xef\xff\x9b\xff\x90\xff\x8e\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xff\x00\x00\x8a\xff\xf4\xff\xcc\xff\xcb\xff\xa1\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xff\x00\x00\xc8\xff\xce\xff\xac\xff\xcf\xff\xd0\xff\xca\xff\x00\x00\x00\x00\x88\xff\x00\x00\x00\x00\x00\x00\x99\xff\x97\xff\x00\x00\x00\x00\x00\x00\x9f\xff\x00\x00\xb1\xff\xbb\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xeb\xff\xec\xff\xbe\xff\xc5\xff\xc6\xff\x00\x00\x00\x00\xa7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\xff\xa9\xff\x00\x00\x95\xff\x00\x00\x00\x00\x91\xff\x00\x00\x96\xff\x00\x00\x00\x00\x00\x00\x00\x00\x89\xff\x00\x00\xa0\xff\xab\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\xff\x00\x00\x86\xff\x00\x00\x00\x00\xfc\xff\xfb\xff\x00\x00\x00\x00\x87\xff\xb4\xff\x00\x00\x00\x00\xb5\xff\x00\x00\x00\x00\xc0\xff\x00\x00\x00\x00\xc4\xff\x00\x00\x00\x00\xc9\xff\x00\x00\xf1\xff\xf2\xff\x00\x00\x8f\xff\x93\xff\x00\x00\x94\xff\x9e\xff\x00\x00\x00\x00\xa3\xff\x00\x00\x00\x00\xa4\xff\xa5\xff\x00\x00\x00\x00\xf3\xff\xb6\xff\xbc\xff\x00\x00\x00\x00\xaa\xff\xb2\xff\x92\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9d\xff\x00\x00\x00\x00\xae\xff\x00\x00\xad\xff\x00\x00\xf9\xff\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xff\xc3\xff\x9c\xff\xf0\xff\x00\x00\xc2\xff\xa6\xff\xb3\xff\x00\x00\xba\xff\xb8\xff\xb7\xff\xb6\xff\x00\x00\xb0\xff\xaf\xff\xf5\xff\x00\x00\x00\x00\xf7\xff\x00\x00\xc1\xff\xb9\xff\xf8\xff"#
-
-happyCheck :: HappyAddr
-happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x07\x00\x0b\x00\x0b\x00\x0b\x00\x09\x00\x0a\x00\x0b\x00\x16\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x16\x00\x0b\x00\x0a\x00\x2b\x00\x03\x00\x16\x00\x0a\x00\x2b\x00\x0a\x00\x41\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x0c\x00\x47\x00\x09\x00\x0b\x00\x0b\x00\x03\x00\x25\x00\x09\x00\x3e\x00\x0b\x00\x29\x00\x2a\x00\x3e\x00\x0c\x00\x16\x00\x33\x00\x34\x00\x35\x00\x0c\x00\x09\x00\x33\x00\x34\x00\x2c\x00\x3a\x00\x39\x00\x38\x00\x10\x00\x3a\x00\x2c\x00\x3a\x00\x2c\x00\x43\x00\x2c\x00\x40\x00\x46\x00\x42\x00\x46\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x33\x00\x34\x00\x35\x00\x46\x00\x09\x00\x42\x00\x0b\x00\x2c\x00\x3a\x00\x0e\x00\x0f\x00\x10\x00\x0c\x00\x3a\x00\x0c\x00\x18\x00\x43\x00\x16\x00\x0c\x00\x46\x00\x0c\x00\x11\x00\x12\x00\x38\x00\x39\x00\x3a\x00\x0c\x00\x2c\x00\x0c\x00\x2c\x00\x3f\x00\x40\x00\x25\x00\x42\x00\x09\x00\x09\x00\x29\x00\x2a\x00\x37\x00\x0c\x00\x37\x00\x10\x00\x10\x00\x03\x00\x2c\x00\x36\x00\x33\x00\x34\x00\x08\x00\x03\x00\x2c\x00\x38\x00\x2c\x00\x3a\x00\x3b\x00\x11\x00\x12\x00\x03\x00\x2c\x00\x40\x00\x2c\x00\x42\x00\x08\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x02\x00\x03\x00\x2c\x00\x03\x00\x09\x00\x0a\x00\x0b\x00\x07\x00\x03\x00\x0e\x00\x0f\x00\x10\x00\x38\x00\x03\x00\x3a\x00\x3a\x00\x03\x00\x16\x00\x0e\x00\x0f\x00\x40\x00\x40\x00\x42\x00\x42\x00\x16\x00\x00\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x13\x00\x06\x00\x25\x00\x17\x00\x18\x00\x19\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x03\x00\x11\x00\x12\x00\x09\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x2b\x00\x3a\x00\x03\x00\x29\x00\x2a\x00\x42\x00\x07\x00\x40\x00\x2e\x00\x42\x00\x03\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x03\x00\x03\x00\x0b\x00\x03\x00\x09\x00\x07\x00\x0b\x00\x0b\x00\x03\x00\x0e\x00\x0f\x00\x10\x00\x07\x00\x17\x00\x18\x00\x19\x00\x42\x00\x16\x00\x3c\x00\x3d\x00\x17\x00\x18\x00\x19\x00\x17\x00\x18\x00\x19\x00\x01\x00\x07\x00\x03\x00\x04\x00\x18\x00\x06\x00\x25\x00\x15\x00\x16\x00\x03\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x3a\x00\x11\x00\x12\x00\x07\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x2c\x00\x3a\x00\x3b\x00\x17\x00\x18\x00\x19\x00\x18\x00\x40\x00\x14\x00\x42\x00\x2b\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x10\x00\x11\x00\x12\x00\x13\x00\x09\x00\x2d\x00\x0b\x00\x15\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x0b\x00\x43\x00\x09\x00\x39\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x2d\x00\x0a\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x42\x00\x06\x00\x25\x00\x14\x00\x3a\x00\x42\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x07\x00\x11\x00\x12\x00\x30\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x3a\x00\x3a\x00\x2c\x00\x01\x00\x2c\x00\x42\x00\x2f\x00\x40\x00\x39\x00\x42\x00\x2c\x00\x44\x00\x45\x00\x46\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x3a\x00\x2c\x00\x05\x00\x2d\x00\x0b\x00\x3a\x00\x0b\x00\x3a\x00\x31\x00\x32\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x06\x00\x42\x00\x3a\x00\x43\x00\x09\x00\x42\x00\x3a\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x08\x00\x42\x00\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\xff\xff\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\xff\xff\x25\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\x0b\x00\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
-
-happyTable :: HappyAddr
-happyTable = HappyA# "\x00\x00\x10\x00\x11\x00\x12\x00\x45\x00\xd1\x00\x2f\x00\x14\x00\x13\x00\xb0\x00\x14\x00\x99\x00\x32\x00\x15\x00\x16\x00\x17\x00\x18\x00\x47\x00\xef\x00\xdf\x00\x02\x01\x18\x00\xed\x00\xa4\x00\xb7\x00\x29\x00\x9f\x00\x8b\x00\x08\x00\x8c\x00\x01\x01\xff\xff\x2e\x00\x8e\x00\x2f\x00\xf6\x00\x19\x00\x31\x00\xe0\x00\x32\x00\x1a\x00\x1b\x00\xa5\x00\x08\x01\x18\x00\x8f\x00\x90\x00\xd2\x00\x02\x01\x13\x00\x1c\x00\x1d\x00\xf0\x00\x30\x00\x46\x00\x1e\x00\x17\x00\x1f\x00\xa0\x00\x33\x00\xa0\x00\xd3\x00\xa0\x00\x21\x00\xd4\x00\x22\x00\x25\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x8f\x00\x90\x00\x91\x00\x48\x00\x13\x00\x22\x00\x14\x00\xa0\x00\x30\x00\x15\x00\x16\x00\x17\x00\xf9\x00\x33\x00\xfb\x00\x49\x00\x92\x00\x18\x00\xdc\x00\x93\x00\xe6\x00\xf4\x00\x0a\x00\x96\x00\x97\x00\x1f\x00\xe8\x00\x9b\x00\xcd\x00\x9b\x00\x98\x00\x21\x00\x19\x00\x22\x00\x13\x00\x13\x00\x1a\x00\x1b\x00\x9c\x00\xa1\x00\x9d\x00\x17\x00\x17\x00\x33\x00\xa0\x00\x4a\x00\x1c\x00\x1d\x00\x87\x00\xbe\x00\xa0\x00\x1e\x00\xa0\x00\x1f\x00\x20\x00\xe2\x00\x0a\x00\x33\x00\xa0\x00\x21\x00\xa0\x00\x22\x00\x34\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\xea\x00\xeb\x00\xa0\x00\x35\x00\x13\x00\x3f\x00\x14\x00\x88\x00\xbf\x00\x15\x00\x16\x00\x17\x00\xcb\x00\x03\x00\x1f\x00\x1f\x00\xc7\x00\x18\x00\xcf\x00\x08\x00\x21\x00\x21\x00\x22\x00\x22\x00\x99\x00\x25\x00\x26\x00\x89\x00\x03\x00\x04\x00\xa1\x00\x05\x00\x19\x00\xdd\x00\x0d\x00\x0e\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\xb0\x00\x09\x00\x0a\x00\x4a\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\x00\x01\x1f\x00\x35\x00\x4c\x00\x4d\x00\x22\x00\x36\x00\x21\x00\x4e\x00\x22\x00\x03\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x03\x00\x35\x00\x04\x01\x03\x00\x13\x00\x40\x00\x14\x00\xee\x00\x35\x00\x15\x00\x16\x00\x17\x00\x41\x00\xc9\x00\x0d\x00\x0e\x00\x22\x00\x18\x00\x2a\x00\x2b\x00\xcb\x00\x0d\x00\x0e\x00\x94\x00\x0d\x00\x0e\x00\xb2\x00\x45\x00\x03\x00\x04\x00\xfa\x00\x05\x00\x19\x00\xad\x00\x43\x00\x03\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\xda\x00\x09\x00\x0a\x00\x45\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\xfb\x00\x1f\x00\x20\x00\x2c\x00\x0d\x00\x0e\x00\xdd\x00\x21\x00\xe2\x00\x22\x00\xe4\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x52\x00\x53\x00\x54\x00\x55\x00\x13\x00\xe5\x00\x14\x00\x42\x00\x43\x00\x15\x00\x16\x00\x17\x00\xe7\x00\xe9\x00\xb4\x00\xb5\x00\x46\x00\x18\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xb6\x00\xb8\x00\x02\x00\xbb\x00\x03\x00\x04\x00\x22\x00\x05\x00\x19\x00\xc2\x00\xc3\x00\x22\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\x45\x00\x09\x00\x0a\x00\xd5\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\xce\x00\x1f\x00\x9b\x00\xd6\x00\xa6\x00\x22\x00\x8b\x00\x21\x00\x46\x00\x22\x00\x9b\x00\x23\x00\x24\x00\x25\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xa3\x00\xa6\x00\x9e\x00\xa7\x00\xa8\x00\xaa\x00\xab\x00\xad\x00\xfd\x00\xfe\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xe1\x00\x22\x00\xb2\x00\x28\x00\x2c\x00\x22\x00\x39\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xc9\x00\x22\x00\x00\x00\x00\x00\x00\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x0a\x01\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x06\x01\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xb9\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xbc\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x00\x00\x67\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x00\x00\x00\x00\x00\x00\x03\x00\x3b\x00\xf0\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xf1\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xd7\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xda\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xb9\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xbc\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xce\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x93\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xae\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x3c\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x3d\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x06\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x07\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xfe\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x04\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf2\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf3\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf7\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xd6\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xe9\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xbd\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc0\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc3\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc4\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc6\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6b\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6c\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6d\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x70\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x71\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x72\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x73\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x74\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x75\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x76\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x77\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x78\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x79\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7b\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7c\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7d\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x80\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x81\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x82\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x83\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x84\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x85\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x86\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x98\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xa8\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xab\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x37\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x39\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
-
-happyReduceArr = array (1, 121) [
-	(1 , happyReduce_1),
-	(2 , happyReduce_2),
-	(3 , happyReduce_3),
-	(4 , happyReduce_4),
-	(5 , happyReduce_5),
-	(6 , happyReduce_6),
-	(7 , happyReduce_7),
-	(8 , happyReduce_8),
-	(9 , happyReduce_9),
-	(10 , happyReduce_10),
-	(11 , happyReduce_11),
-	(12 , happyReduce_12),
-	(13 , happyReduce_13),
-	(14 , happyReduce_14),
-	(15 , happyReduce_15),
-	(16 , happyReduce_16),
-	(17 , happyReduce_17),
-	(18 , happyReduce_18),
-	(19 , happyReduce_19),
-	(20 , happyReduce_20),
-	(21 , happyReduce_21),
-	(22 , happyReduce_22),
-	(23 , happyReduce_23),
-	(24 , happyReduce_24),
-	(25 , happyReduce_25),
-	(26 , happyReduce_26),
-	(27 , happyReduce_27),
-	(28 , happyReduce_28),
-	(29 , happyReduce_29),
-	(30 , happyReduce_30),
-	(31 , happyReduce_31),
-	(32 , happyReduce_32),
-	(33 , happyReduce_33),
-	(34 , happyReduce_34),
-	(35 , happyReduce_35),
-	(36 , happyReduce_36),
-	(37 , happyReduce_37),
-	(38 , happyReduce_38),
-	(39 , happyReduce_39),
-	(40 , happyReduce_40),
-	(41 , happyReduce_41),
-	(42 , happyReduce_42),
-	(43 , happyReduce_43),
-	(44 , happyReduce_44),
-	(45 , happyReduce_45),
-	(46 , happyReduce_46),
-	(47 , happyReduce_47),
-	(48 , happyReduce_48),
-	(49 , happyReduce_49),
-	(50 , happyReduce_50),
-	(51 , happyReduce_51),
-	(52 , happyReduce_52),
-	(53 , happyReduce_53),
-	(54 , happyReduce_54),
-	(55 , happyReduce_55),
-	(56 , happyReduce_56),
-	(57 , happyReduce_57),
-	(58 , happyReduce_58),
-	(59 , happyReduce_59),
-	(60 , happyReduce_60),
-	(61 , happyReduce_61),
-	(62 , happyReduce_62),
-	(63 , happyReduce_63),
-	(64 , happyReduce_64),
-	(65 , happyReduce_65),
-	(66 , happyReduce_66),
-	(67 , happyReduce_67),
-	(68 , happyReduce_68),
-	(69 , happyReduce_69),
-	(70 , happyReduce_70),
-	(71 , happyReduce_71),
-	(72 , happyReduce_72),
-	(73 , happyReduce_73),
-	(74 , happyReduce_74),
-	(75 , happyReduce_75),
-	(76 , happyReduce_76),
-	(77 , happyReduce_77),
-	(78 , happyReduce_78),
-	(79 , happyReduce_79),
-	(80 , happyReduce_80),
-	(81 , happyReduce_81),
-	(82 , happyReduce_82),
-	(83 , happyReduce_83),
-	(84 , happyReduce_84),
-	(85 , happyReduce_85),
-	(86 , happyReduce_86),
-	(87 , happyReduce_87),
-	(88 , happyReduce_88),
-	(89 , happyReduce_89),
-	(90 , happyReduce_90),
-	(91 , happyReduce_91),
-	(92 , happyReduce_92),
-	(93 , happyReduce_93),
-	(94 , happyReduce_94),
-	(95 , happyReduce_95),
-	(96 , happyReduce_96),
-	(97 , happyReduce_97),
-	(98 , happyReduce_98),
-	(99 , happyReduce_99),
-	(100 , happyReduce_100),
-	(101 , happyReduce_101),
-	(102 , happyReduce_102),
-	(103 , happyReduce_103),
-	(104 , happyReduce_104),
-	(105 , happyReduce_105),
-	(106 , happyReduce_106),
-	(107 , happyReduce_107),
-	(108 , happyReduce_108),
-	(109 , happyReduce_109),
-	(110 , happyReduce_110),
-	(111 , happyReduce_111),
-	(112 , happyReduce_112),
-	(113 , happyReduce_113),
-	(114 , happyReduce_114),
-	(115 , happyReduce_115),
-	(116 , happyReduce_116),
-	(117 , happyReduce_117),
-	(118 , happyReduce_118),
-	(119 , happyReduce_119),
-	(120 , happyReduce_120),
-	(121 , happyReduce_121)
-	]
-
-happy_n_terms = 72 :: Int
-happy_n_nonterms = 26 :: Int
-
-happyReduce_1 = happySpecReduce_1  0# happyReduction_1
-happyReduction_1 happy_x_1
-	 =  case happyOut5 happy_x_1 of { happy_var_1 -> 
-	happyIn4
-		 ([happy_var_1]
-	)}
-
-happyReduce_2 = happySpecReduce_2  0# happyReduction_2
-happyReduction_2 happy_x_2
-	happy_x_1
-	 =  case happyOut5 happy_x_1 of { happy_var_1 -> 
-	happyIn4
-		 ([happy_var_1]
-	)}
-
-happyReduce_3 = happySpecReduce_3  0# happyReduction_3
-happyReduction_3 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut4 happy_x_1 of { happy_var_1 -> 
-	case happyOut5 happy_x_3 of { happy_var_3 -> 
-	happyIn4
-		 (happy_var_1++[happy_var_3]
-	)}}
-
-happyReduce_4 = happyReduce 4# 0# happyReduction_4
-happyReduction_4 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut4 happy_x_1 of { happy_var_1 -> 
-	case happyOut5 happy_x_3 of { happy_var_3 -> 
-	happyIn4
-		 (happy_var_1++[happy_var_3]
-	) `HappyStk` happyRest}}
-
-happyReduce_5 = happySpecReduce_1  1# happyReduction_5
-happyReduction_5 happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	happyIn5
-		 (happy_var_1
-	)}
-
-happyReduce_6 = happyReduce 5# 1# happyReduction_6
-happyReduction_6 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut7 happy_x_3 of { happy_var_3 -> 
-	case happyOut8 happy_x_5 of { happy_var_5 -> 
-	happyIn5
-		 (Ast "variable" [happy_var_3,happy_var_5]
-	) `HappyStk` happyRest}}
-
-happyReduce_7 = happyReduce 9# 1# happyReduction_7
-happyReduction_7 (happy_x_9 `HappyStk`
-	happy_x_8 `HappyStk`
-	happy_x_7 `HappyStk`
-	happy_x_6 `HappyStk`
-	happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOutTok happy_x_3 of { (QName happy_var_3) -> 
-	case happyOut6 happy_x_5 of { happy_var_5 -> 
-	case happyOut8 happy_x_8 of { happy_var_8 -> 
-	happyIn5
-		 (Ast "function" ([Avar happy_var_3,happy_var_8]++happy_var_5)
-	) `HappyStk` happyRest}}}
-
-happyReduce_8 = happyReduce 8# 1# happyReduction_8
-happyReduction_8 (happy_x_8 `HappyStk`
-	happy_x_7 `HappyStk`
-	happy_x_6 `HappyStk`
-	happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOutTok happy_x_3 of { (QName happy_var_3) -> 
-	case happyOut8 happy_x_7 of { happy_var_7 -> 
-	happyIn5
-		 (Ast "function" [Avar happy_var_3,happy_var_7]
-	) `HappyStk` happyRest}}
-
-happyReduce_9 = happySpecReduce_1  2# happyReduction_9
-happyReduction_9 happy_x_1
-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
-	happyIn6
-		 ([happy_var_1]
-	)}
-
-happyReduce_10 = happySpecReduce_3  2# happyReduction_10
-happyReduction_10 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut6 happy_x_1 of { happy_var_1 -> 
-	case happyOut7 happy_x_3 of { happy_var_3 -> 
-	happyIn6
-		 (happy_var_1++[happy_var_3]
-	)}}
-
-happyReduce_11 = happySpecReduce_1  3# happyReduction_11
-happyReduction_11 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Variable happy_var_1) -> 
-	happyIn7
-		 (Avar happy_var_1
-	)}
-
-happyReduce_12 = happyReduce 5# 4# happyReduction_12
-happyReduction_12 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut10 happy_x_1 of { happy_var_1 -> 
-	case happyOut13 happy_x_2 of { happy_var_2 -> 
-	case happyOut14 happy_x_3 of { happy_var_3 -> 
-	case happyOut8 happy_x_5 of { happy_var_5 -> 
-	happyIn8
-		 ((snd happy_var_3) (happy_var_1 (happy_var_2 ((fst happy_var_3) happy_var_5)))
-	) `HappyStk` happyRest}}}}
-
-happyReduce_13 = happyReduce 4# 4# happyReduction_13
-happyReduction_13 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut11 happy_x_2 of { happy_var_2 -> 
-	case happyOut8 happy_x_4 of { happy_var_4 -> 
-	happyIn8
-		 (call "some" [happy_var_2 happy_var_4]
-	) `HappyStk` happyRest}}
-
-happyReduce_14 = happyReduce 4# 4# happyReduction_14
-happyReduction_14 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut11 happy_x_2 of { happy_var_2 -> 
-	case happyOut8 happy_x_4 of { happy_var_4 -> 
-	happyIn8
-		 (call "not" [call "some" [happy_var_2 (call "not" [happy_var_4])]]
-	) `HappyStk` happyRest}}
-
-happyReduce_15 = happyReduce 6# 4# happyReduction_15
-happyReduction_15 (happy_x_6 `HappyStk`
-	happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut8 happy_x_2 of { happy_var_2 -> 
-	case happyOut8 happy_x_4 of { happy_var_4 -> 
-	case happyOut8 happy_x_6 of { happy_var_6 -> 
-	happyIn8
-		 (call "if" [happy_var_2,happy_var_4,happy_var_6]
-	) `HappyStk` happyRest}}}
-
-happyReduce_16 = happySpecReduce_1  4# happyReduction_16
-happyReduction_16 happy_x_1
-	 =  case happyOut24 happy_x_1 of { happy_var_1 -> 
-	happyIn8
-		 (happy_var_1
-	)}
-
-happyReduce_17 = happySpecReduce_1  4# happyReduction_17
-happyReduction_17 happy_x_1
-	 =  case happyOut18 happy_x_1 of { happy_var_1 -> 
-	happyIn8
-		 (happy_var_1
-	)}
-
-happyReduce_18 = happySpecReduce_1  4# happyReduction_18
-happyReduction_18 happy_x_1
-	 =  case happyOut17 happy_x_1 of { happy_var_1 -> 
-	happyIn8
-		 (happy_var_1
-	)}
-
-happyReduce_19 = happySpecReduce_3  4# happyReduction_19
-happyReduction_19 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "to" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_20 = happySpecReduce_3  4# happyReduction_20
-happyReduction_20 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "+" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_21 = happySpecReduce_3  4# happyReduction_21
-happyReduction_21 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "-" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_22 = happySpecReduce_3  4# happyReduction_22
-happyReduction_22 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "*" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_23 = happySpecReduce_3  4# happyReduction_23
-happyReduction_23 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "div" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_24 = happySpecReduce_3  4# happyReduction_24
-happyReduction_24 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "idiv" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_25 = happySpecReduce_3  4# happyReduction_25
-happyReduction_25 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "mod" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_26 = happySpecReduce_3  4# happyReduction_26
-happyReduction_26 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "=" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_27 = happySpecReduce_3  4# happyReduction_27
-happyReduction_27 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "!=" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_28 = happySpecReduce_3  4# happyReduction_28
-happyReduction_28 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "<" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_29 = happySpecReduce_3  4# happyReduction_29
-happyReduction_29 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "<=" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_30 = happySpecReduce_3  4# happyReduction_30
-happyReduction_30 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call ">" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_31 = happySpecReduce_3  4# happyReduction_31
-happyReduction_31 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call ">=" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_32 = happySpecReduce_3  4# happyReduction_32
-happyReduction_32 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "<<" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_33 = happySpecReduce_3  4# happyReduction_33
-happyReduction_33 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call ">>" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_34 = happySpecReduce_3  4# happyReduction_34
-happyReduction_34 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "is" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_35 = happySpecReduce_3  4# happyReduction_35
-happyReduction_35 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "eq" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_36 = happySpecReduce_3  4# happyReduction_36
-happyReduction_36 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "ne" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_37 = happySpecReduce_3  4# happyReduction_37
-happyReduction_37 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "lt" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_38 = happySpecReduce_3  4# happyReduction_38
-happyReduction_38 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "le" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_39 = happySpecReduce_3  4# happyReduction_39
-happyReduction_39 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "gt" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_40 = happySpecReduce_3  4# happyReduction_40
-happyReduction_40 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "ge" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_41 = happySpecReduce_3  4# happyReduction_41
-happyReduction_41 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "and" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_42 = happySpecReduce_3  4# happyReduction_42
-happyReduction_42 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "or" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_43 = happySpecReduce_3  4# happyReduction_43
-happyReduction_43 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "not" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_44 = happySpecReduce_3  4# happyReduction_44
-happyReduction_44 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "union" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_45 = happySpecReduce_3  4# happyReduction_45
-happyReduction_45 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "intersect" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_46 = happySpecReduce_3  4# happyReduction_46
-happyReduction_46 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
-		 (call "except" [happy_var_1,happy_var_3]
-	)}}
-
-happyReduce_47 = happySpecReduce_2  4# happyReduction_47
-happyReduction_47 happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
-	happyIn8
-		 (call "uplus" [happy_var_2]
-	)}
-
-happyReduce_48 = happySpecReduce_2  4# happyReduction_48
-happyReduction_48 happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
-	happyIn8
-		 (call "uminus" [happy_var_2]
-	)}
-
-happyReduce_49 = happySpecReduce_2  4# happyReduction_49
-happyReduction_49 happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
-	happyIn8
-		 (call "not" [happy_var_2]
-	)}
-
-happyReduce_50 = happySpecReduce_1  4# happyReduction_50
-happyReduction_50 happy_x_1
-	 =  case happyOut21 happy_x_1 of { happy_var_1 -> 
-	happyIn8
-		 (happy_var_1
-	)}
-
-happyReduce_51 = happySpecReduce_1  4# happyReduction_51
-happyReduction_51 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (TInteger happy_var_1) -> 
-	happyIn8
-		 (Aint happy_var_1
-	)}
-
-happyReduce_52 = happySpecReduce_1  4# happyReduction_52
-happyReduction_52 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (TFloat happy_var_1) -> 
-	happyIn8
-		 (Afloat happy_var_1
-	)}
-
-happyReduce_53 = happySpecReduce_1  5# happyReduction_53
-happyReduction_53 happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	happyIn9
-		 ([happy_var_1]
-	)}
-
-happyReduce_54 = happySpecReduce_3  5# happyReduction_54
-happyReduction_54 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut9 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn9
-		 (happy_var_1++[happy_var_3]
-	)}}
-
-happyReduce_55 = happySpecReduce_2  6# happyReduction_55
-happyReduction_55 happy_x_2
-	happy_x_1
-	 =  case happyOut11 happy_x_2 of { happy_var_2 -> 
-	happyIn10
-		 (happy_var_2
-	)}
-
-happyReduce_56 = happySpecReduce_2  6# happyReduction_56
-happyReduction_56 happy_x_2
-	happy_x_1
-	 =  case happyOut12 happy_x_2 of { happy_var_2 -> 
-	happyIn10
-		 (happy_var_2
-	)}
-
-happyReduce_57 = happySpecReduce_3  6# happyReduction_57
-happyReduction_57 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut10 happy_x_1 of { happy_var_1 -> 
-	case happyOut11 happy_x_3 of { happy_var_3 -> 
-	happyIn10
-		 (happy_var_1 . happy_var_3
-	)}}
-
-happyReduce_58 = happySpecReduce_3  6# happyReduction_58
-happyReduction_58 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut10 happy_x_1 of { happy_var_1 -> 
-	case happyOut12 happy_x_3 of { happy_var_3 -> 
-	happyIn10
-		 (happy_var_1 . happy_var_3
-	)}}
-
-happyReduce_59 = happySpecReduce_3  7# happyReduction_59
-happyReduction_59 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn11
-		 (\x -> Ast "for" [happy_var_1,Avar "$",happy_var_3,x]
-	)}}
-
-happyReduce_60 = happyReduce 5# 7# happyReduction_60
-happyReduction_60 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut7 happy_x_1 of { happy_var_1 -> 
-	case happyOut7 happy_x_3 of { happy_var_3 -> 
-	case happyOut8 happy_x_5 of { happy_var_5 -> 
-	happyIn11
-		 (\x -> Ast "for" [happy_var_1,happy_var_3,happy_var_5,x]
-	) `HappyStk` happyRest}}}
-
-happyReduce_61 = happyReduce 5# 7# happyReduction_61
-happyReduction_61 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut11 happy_x_1 of { happy_var_1 -> 
-	case happyOut7 happy_x_3 of { happy_var_3 -> 
-	case happyOut8 happy_x_5 of { happy_var_5 -> 
-	happyIn11
-		 (\x -> happy_var_1(Ast "for" [happy_var_3,Avar "$",happy_var_5,x])
-	) `HappyStk` happyRest}}}
-
-happyReduce_62 = happyReduce 7# 7# happyReduction_62
-happyReduction_62 (happy_x_7 `HappyStk`
-	happy_x_6 `HappyStk`
-	happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut11 happy_x_1 of { happy_var_1 -> 
-	case happyOut7 happy_x_3 of { happy_var_3 -> 
-	case happyOut7 happy_x_5 of { happy_var_5 -> 
-	case happyOut8 happy_x_7 of { happy_var_7 -> 
-	happyIn11
-		 (\x -> happy_var_1(Ast "for" [happy_var_3,happy_var_5,happy_var_7,x])
-	) `HappyStk` happyRest}}}}
-
-happyReduce_63 = happySpecReduce_3  8# happyReduction_63
-happyReduction_63 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
-		 (\x -> Ast "let" [happy_var_1,happy_var_3,x]
-	)}}
-
-happyReduce_64 = happyReduce 5# 8# happyReduction_64
-happyReduction_64 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut12 happy_x_1 of { happy_var_1 -> 
-	case happyOut7 happy_x_3 of { happy_var_3 -> 
-	case happyOut8 happy_x_5 of { happy_var_5 -> 
-	happyIn12
-		 (\x -> happy_var_1(Ast "let" [happy_var_3,happy_var_5,x])
-	) `HappyStk` happyRest}}}
-
-happyReduce_65 = happySpecReduce_2  9# happyReduction_65
-happyReduction_65 happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
-	happyIn13
-		 (\x -> Ast "predicate" [happy_var_2,x]
-	)}
-
-happyReduce_66 = happySpecReduce_0  9# happyReduction_66
-happyReduction_66  =  happyIn13
-		 (id
-	)
-
-happyReduce_67 = happySpecReduce_3  10# happyReduction_67
-happyReduction_67 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut15 happy_x_3 of { happy_var_3 -> 
-	happyIn14
-		 ((\x -> Ast "sortTuple" (x:(fst happy_var_3)),
-                                                           \x -> Ast "sort" (x:(snd happy_var_3)))
-	)}
-
-happyReduce_68 = happySpecReduce_0  10# happyReduction_68
-happyReduction_68  =  happyIn14
-		 ((id,id)
-	)
-
-happyReduce_69 = happySpecReduce_2  11# happyReduction_69
-happyReduction_69 happy_x_2
-	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut16 happy_x_2 of { happy_var_2 -> 
-	happyIn15
-		 (([happy_var_1],[happy_var_2])
-	)}}
-
-happyReduce_70 = happyReduce 4# 11# happyReduction_70
-happyReduction_70 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut15 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	case happyOut16 happy_x_4 of { happy_var_4 -> 
-	happyIn15
-		 (((fst happy_var_1)++[happy_var_3],(snd happy_var_1)++[happy_var_4])
-	) `HappyStk` happyRest}}}
-
-happyReduce_71 = happySpecReduce_1  12# happyReduction_71
-happyReduction_71 happy_x_1
-	 =  happyIn16
-		 (Avar "ascending"
-	)
-
-happyReduce_72 = happySpecReduce_1  12# happyReduction_72
-happyReduction_72 happy_x_1
-	 =  happyIn16
-		 (Avar "descending"
-	)
-
-happyReduce_73 = happySpecReduce_0  12# happyReduction_73
-happyReduction_73  =  happyIn16
-		 (Avar "ascending"
-	)
-
-happyReduce_74 = happyReduce 4# 13# happyReduction_74
-happyReduction_74 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOutTok happy_x_3 of { (QName happy_var_3) -> 
-	happyIn17
-		 (call "element" [Avar happy_var_3]
-	) `HappyStk` happyRest}
-
-happyReduce_75 = happyReduce 4# 13# happyReduction_75
-happyReduction_75 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOutTok happy_x_3 of { (QName happy_var_3) -> 
-	happyIn17
-		 (call "attribute" [Avar happy_var_3]
-	) `HappyStk` happyRest}
-
-happyReduce_76 = happyReduce 6# 14# happyReduction_76
-happyReduction_76 (happy_x_6 `HappyStk`
-	happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut19 happy_x_1 of { happy_var_1 -> 
-	case happyOut20 happy_x_3 of { happy_var_3 -> 
-	case happyOutTok happy_x_5 of { (QName happy_var_5) -> 
-	happyIn18
-		 (if head happy_var_1 == Astring happy_var_5
-						  	     then Ast "element_construction" (happy_var_1++[Ast "append" happy_var_3])
-                                                          else parseError [TError ("Unmatched tags in element construction: "
-                                                                                   ++(show (head happy_var_1))++" '"++happy_var_5++"'")]
-	) `HappyStk` happyRest}}}
-
-happyReduce_77 = happyReduce 5# 14# happyReduction_77
-happyReduction_77 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut19 happy_x_1 of { happy_var_1 -> 
-	case happyOutTok happy_x_4 of { (QName happy_var_4) -> 
-	happyIn18
-		 (if head happy_var_1 == Astring happy_var_4
-							     then Ast "element_construction" (happy_var_1++[Ast "append" []])
-                                                          else parseError [TError ("Unmatched tags in element construction: "
-                                                                                   ++(show (head happy_var_1))++" '"++happy_var_4++"'")]
-	) `HappyStk` happyRest}}
-
-happyReduce_78 = happySpecReduce_2  14# happyReduction_78
-happyReduction_78 happy_x_2
-	happy_x_1
-	 =  case happyOut19 happy_x_1 of { happy_var_1 -> 
-	happyIn18
-		 (Ast "element_construction" (happy_var_1++[Ast "append" []])
-	)}
-
-happyReduce_79 = happyReduce 7# 14# happyReduction_79
-happyReduction_79 (happy_x_7 `HappyStk`
-	happy_x_6 `HappyStk`
-	happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut8 happy_x_3 of { happy_var_3 -> 
-	case happyOut9 happy_x_6 of { happy_var_6 -> 
-	happyIn18
-		 (Ast "element_construction" [happy_var_3,Ast "attributes" [],concatenateAll happy_var_6]
-	) `HappyStk` happyRest}}
-
-happyReduce_80 = happyReduce 7# 14# happyReduction_80
-happyReduction_80 (happy_x_7 `HappyStk`
-	happy_x_6 `HappyStk`
-	happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut8 happy_x_3 of { happy_var_3 -> 
-	case happyOut9 happy_x_6 of { happy_var_6 -> 
-	happyIn18
-		 (Ast "attribute_construction" [happy_var_3,concatenateAll happy_var_6]
-	) `HappyStk` happyRest}}
-
-happyReduce_81 = happyReduce 5# 14# happyReduction_81
-happyReduction_81 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
-	case happyOut9 happy_x_4 of { happy_var_4 -> 
-	happyIn18
-		 (Ast "element_construction" [Astring happy_var_2,Ast "attributes" [],concatenateAll happy_var_4]
-	) `HappyStk` happyRest}}
-
-happyReduce_82 = happyReduce 5# 14# happyReduction_82
-happyReduction_82 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
-	case happyOut9 happy_x_4 of { happy_var_4 -> 
-	happyIn18
-		 (Ast "attribute_construction" [Astring happy_var_2,concatenateAll happy_var_4]
-	) `HappyStk` happyRest}}
-
-happyReduce_83 = happySpecReduce_2  15# happyReduction_83
-happyReduction_83 happy_x_2
-	happy_x_1
-	 =  case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
-	happyIn19
-		 ([Astring happy_var_2,Ast "attributes" []]
-	)}
-
-happyReduce_84 = happySpecReduce_3  15# happyReduction_84
-happyReduction_84 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
-	case happyOut23 happy_x_3 of { happy_var_3 -> 
-	happyIn19
-		 ([Astring happy_var_2,Ast "attributes" happy_var_3]
-	)}}
-
-happyReduce_85 = happySpecReduce_3  16# happyReduction_85
-happyReduction_85 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut9 happy_x_2 of { happy_var_2 -> 
-	happyIn20
-		 ([concatenateAll happy_var_2]
-	)}
-
-happyReduce_86 = happySpecReduce_1  16# happyReduction_86
-happyReduction_86 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (TString happy_var_1) -> 
-	happyIn20
-		 ([Astring happy_var_1]
-	)}
-
-happyReduce_87 = happySpecReduce_1  16# happyReduction_87
-happyReduction_87 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (XMLtext happy_var_1) -> 
-	happyIn20
-		 ([Astring happy_var_1]
-	)}
-
-happyReduce_88 = happySpecReduce_1  16# happyReduction_88
-happyReduction_88 happy_x_1
-	 =  case happyOut18 happy_x_1 of { happy_var_1 -> 
-	happyIn20
-		 ([happy_var_1]
-	)}
-
-happyReduce_89 = happyReduce 4# 16# happyReduction_89
-happyReduction_89 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut20 happy_x_1 of { happy_var_1 -> 
-	case happyOut9 happy_x_3 of { happy_var_3 -> 
-	happyIn20
-		 (happy_var_1++[concatenateAll happy_var_3]
-	) `HappyStk` happyRest}}
-
-happyReduce_90 = happySpecReduce_2  16# happyReduction_90
-happyReduction_90 happy_x_2
-	happy_x_1
-	 =  case happyOut20 happy_x_1 of { happy_var_1 -> 
-	case happyOutTok happy_x_2 of { (TString happy_var_2) -> 
-	happyIn20
-		 (happy_var_1++[Astring happy_var_2]
-	)}}
-
-happyReduce_91 = happySpecReduce_2  16# happyReduction_91
-happyReduction_91 happy_x_2
-	happy_x_1
-	 =  case happyOut20 happy_x_1 of { happy_var_1 -> 
-	case happyOutTok happy_x_2 of { (XMLtext happy_var_2) -> 
-	happyIn20
-		 (happy_var_1++[Astring happy_var_2]
-	)}}
-
-happyReduce_92 = happySpecReduce_2  16# happyReduction_92
-happyReduction_92 happy_x_2
-	happy_x_1
-	 =  case happyOut20 happy_x_1 of { happy_var_1 -> 
-	case happyOut18 happy_x_2 of { happy_var_2 -> 
-	happyIn20
-		 (happy_var_1++[happy_var_2]
-	)}}
-
-happyReduce_93 = happySpecReduce_1  17# happyReduction_93
-happyReduction_93 happy_x_1
-	 =  case happyOut22 happy_x_1 of { happy_var_1 -> 
-	happyIn21
-		 (if length happy_var_1 == 1 then head happy_var_1 else Ast "append" happy_var_1
-	)}
-
-happyReduce_94 = happySpecReduce_1  18# happyReduction_94
-happyReduction_94 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (TString happy_var_1) -> 
-	happyIn22
-		 (if happy_var_1=="" then [] else [Astring happy_var_1]
-	)}
-
-happyReduce_95 = happySpecReduce_3  18# happyReduction_95
-happyReduction_95 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut9 happy_x_2 of { happy_var_2 -> 
-	happyIn22
-		 ([concatenateAll happy_var_2]
-	)}
-
-happyReduce_96 = happySpecReduce_2  18# happyReduction_96
-happyReduction_96 happy_x_2
-	happy_x_1
-	 =  case happyOut22 happy_x_1 of { happy_var_1 -> 
-	case happyOutTok happy_x_2 of { (TString happy_var_2) -> 
-	happyIn22
-		 (if happy_var_2=="" then happy_var_1 else happy_var_1++[Astring happy_var_2]
-	)}}
-
-happyReduce_97 = happyReduce 4# 18# happyReduction_97
-happyReduction_97 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut22 happy_x_1 of { happy_var_1 -> 
-	case happyOut9 happy_x_3 of { happy_var_3 -> 
-	happyIn22
-		 (happy_var_1++[concatenateAll happy_var_3]
-	) `HappyStk` happyRest}}
-
-happyReduce_98 = happySpecReduce_3  19# happyReduction_98
-happyReduction_98 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
-	case happyOut21 happy_x_3 of { happy_var_3 -> 
-	happyIn23
-		 ([Ast "pair" [Astring happy_var_1,happy_var_3]]
-	)}}
-
-happyReduce_99 = happyReduce 4# 19# happyReduction_99
-happyReduction_99 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut23 happy_x_1 of { happy_var_1 -> 
-	case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
-	case happyOut21 happy_x_4 of { happy_var_4 -> 
-	happyIn23
-		 (happy_var_1++[Ast "pair" [Astring happy_var_2,happy_var_4]]
-	) `HappyStk` happyRest}}}
-
-happyReduce_100 = happySpecReduce_1  20# happyReduction_100
-happyReduction_100 happy_x_1
-	 =  case happyOut27 happy_x_1 of { happy_var_1 -> 
-	happyIn24
-		 (Ast "step" (happy_var_1 "child_step" (Avar "."))
-	)}
-
-happyReduce_101 = happySpecReduce_2  20# happyReduction_101
-happyReduction_101 happy_x_2
-	happy_x_1
-	 =  case happyOut27 happy_x_2 of { happy_var_2 -> 
-	happyIn24
-		 (Ast "step" (happy_var_2 "attribute_step" (Avar "."))
-	)}
-
-happyReduce_102 = happySpecReduce_2  20# happyReduction_102
-happyReduction_102 happy_x_2
-	happy_x_1
-	 =  case happyOut27 happy_x_1 of { happy_var_1 -> 
-	case happyOut25 happy_x_2 of { happy_var_2 -> 
-	happyIn24
-		 (Ast "step" [happy_var_2 (Ast "step" (happy_var_1 "child_step" (Avar ".")))]
-	)}}
-
-happyReduce_103 = happySpecReduce_3  20# happyReduction_103
-happyReduction_103 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut27 happy_x_2 of { happy_var_2 -> 
-	case happyOut25 happy_x_3 of { happy_var_3 -> 
-	happyIn24
-		 (Ast "step" (map happy_var_3 (happy_var_2 "attribute_step" (Avar ".")))
-	)}}
-
-happyReduce_104 = happySpecReduce_1  21# happyReduction_104
-happyReduction_104 happy_x_1
-	 =  case happyOut26 happy_x_1 of { happy_var_1 -> 
-	happyIn25
-		 (happy_var_1
-	)}
-
-happyReduce_105 = happySpecReduce_2  21# happyReduction_105
-happyReduction_105 happy_x_2
-	happy_x_1
-	 =  case happyOut25 happy_x_1 of { happy_var_1 -> 
-	case happyOut26 happy_x_2 of { happy_var_2 -> 
-	happyIn25
-		 (happy_var_2 . happy_var_1
-	)}}
-
-happyReduce_106 = happySpecReduce_2  22# happyReduction_106
-happyReduction_106 happy_x_2
-	happy_x_1
-	 =  case happyOut27 happy_x_2 of { happy_var_2 -> 
-	happyIn26
-		 (\e -> Ast "step" (happy_var_2 "child_step" e)
-	)}
-
-happyReduce_107 = happySpecReduce_3  22# happyReduction_107
-happyReduction_107 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut27 happy_x_3 of { happy_var_3 -> 
-	happyIn26
-		 (\e -> Ast "step" (happy_var_3 "attribute_step" e)
-	)}
-
-happyReduce_108 = happySpecReduce_3  22# happyReduction_108
-happyReduction_108 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut27 happy_x_3 of { happy_var_3 -> 
-	happyIn26
-		 (\e -> Ast "step" (happy_var_3 "descendant_step" e)
-	)}
-
-happyReduce_109 = happyReduce 4# 22# happyReduction_109
-happyReduction_109 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut27 happy_x_4 of { happy_var_4 -> 
-	happyIn26
-		 (\e -> Ast "step" (happy_var_4 "attribute_descendant_step" e)
-	) `HappyStk` happyRest}
-
-happyReduce_110 = happySpecReduce_2  22# happyReduction_110
-happyReduction_110 happy_x_2
-	happy_x_1
-	 =  happyIn26
-		 (\e -> Ast "step" [Ast "parent_step" [e]]
-	)
-
-happyReduce_111 = happySpecReduce_1  23# happyReduction_111
-happyReduction_111 happy_x_1
-	 =  case happyOut28 happy_x_1 of { happy_var_1 -> 
-	happyIn27
-		 (\t e -> [happy_var_1 t e]
-	)}
-
-happyReduce_112 = happyReduce 4# 23# happyReduction_112
-happyReduction_112 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut27 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn27
-		 (\t e -> (happy_var_1 t e)++[happy_var_3]
-	) `HappyStk` happyRest}}
-
-happyReduce_113 = happySpecReduce_1  24# happyReduction_113
-happyReduction_113 happy_x_1
-	 =  case happyOut29 happy_x_1 of { happy_var_1 -> 
-	happyIn28
-		 (\t e -> happy_var_1 t e
-	)}
-
-happyReduce_114 = happySpecReduce_1  24# happyReduction_114
-happyReduction_114 happy_x_1
-	 =  happyIn28
-		 (\t e -> Ast t [Astring "*",e]
-	)
-
-happyReduce_115 = happySpecReduce_1  24# happyReduction_115
-happyReduction_115 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
-	happyIn28
-		 (\t e -> Ast t [Astring happy_var_1,e]
-	)}
-
-happyReduce_116 = happySpecReduce_1  25# happyReduction_116
-happyReduction_116 happy_x_1
-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
-	happyIn29
-		 (\_ _ -> happy_var_1
-	)}
-
-happyReduce_117 = happySpecReduce_1  25# happyReduction_117
-happyReduction_117 happy_x_1
-	 =  happyIn29
-		 (\_ e -> e
-	)
-
-happyReduce_118 = happySpecReduce_3  25# happyReduction_118
-happyReduction_118 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut9 happy_x_2 of { happy_var_2 -> 
-	happyIn29
-		 (\t e -> if e == Avar "."
-                                                                     then concatenateAll happy_var_2
-	                                                          else Ast "context" [e,Astring t,concatenateAll happy_var_2]
-	)}
-
-happyReduce_119 = happySpecReduce_2  25# happyReduction_119
-happyReduction_119 happy_x_2
-	happy_x_1
-	 =  happyIn29
-		 (\_ _ -> call "empty" []
-	)
-
-happyReduce_120 = happyReduce 4# 25# happyReduction_120
-happyReduction_120 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
-	case happyOut9 happy_x_3 of { happy_var_3 -> 
-	happyIn29
-		 (\t e -> if e == Avar "."
-                                                                     then call happy_var_1 happy_var_3
-                                                                  else Ast "context" [e,Astring t,call happy_var_1 happy_var_3]
-	) `HappyStk` happyRest}}
-
-happyReduce_121 = happySpecReduce_3  25# happyReduction_121
-happyReduction_121 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
-	happyIn29
-		 (\_ e -> call happy_var_1 (if e == Avar "." then [] else [e])
-	)}
-
-happyNewToken action sts stk [] =
-	happyDoAction 71# notHappyAtAll action sts stk []
-
-happyNewToken action sts stk (tk:tks) =
-	let cont i = happyDoAction i tk action sts stk tks in
-	case tk of {
-	RETURN -> cont 1#;
-	SOME -> cont 2#;
-	EVERY -> cont 3#;
-	IF -> cont 4#;
-	THEN -> cont 5#;
-	ELSE -> cont 6#;
-	LB -> cont 7#;
-	RB -> cont 8#;
-	LP -> cont 9#;
-	RP -> cont 10#;
-	LSB -> cont 11#;
-	RSB -> cont 12#;
-	TO -> cont 13#;
-	PLUS -> cont 14#;
-	MINUS -> cont 15#;
-	TIMES -> cont 16#;
-	DIV -> cont 17#;
-	IDIV -> cont 18#;
-	MOD -> cont 19#;
-	TEQ -> cont 20#;
-	TNE -> cont 21#;
-	TLT -> cont 22#;
-	TLE -> cont 23#;
-	TGT -> cont 24#;
-	TGE -> cont 25#;
-	PRE -> cont 26#;
-	POST -> cont 27#;
-	IS -> cont 28#;
-	SEQ -> cont 29#;
-	SNE -> cont 30#;
-	SLT -> cont 31#;
-	SLE -> cont 32#;
-	SGT -> cont 33#;
-	SGE -> cont 34#;
-	AND -> cont 35#;
-	OR -> cont 36#;
-	NOT -> cont 37#;
-	UNION -> cont 38#;
-	INTERSECT -> cont 39#;
-	EXCEPT -> cont 40#;
-	FOR -> cont 41#;
-	LET -> cont 42#;
-	IN -> cont 43#;
-	COMMA -> cont 44#;
-	ASSIGN -> cont 45#;
-	WHERE -> cont 46#;
-	ORDER -> cont 47#;
-	BY -> cont 48#;
-	ASCENDING -> cont 49#;
-	DESCENDING -> cont 50#;
-	ELEMENT -> cont 51#;
-	ATTRIBUTE -> cont 52#;
-	STAG -> cont 53#;
-	ETAG -> cont 54#;
-	SATISFIES -> cont 55#;
-	ATSIGN -> cont 56#;
-	SLASH -> cont 57#;
-	QName happy_dollar_dollar -> cont 58#;
-	DECLARE -> cont 59#;
-	FUNCTION -> cont 60#;
-	VARIABLE -> cont 61#;
-	AT -> cont 62#;
-	DOTS -> cont 63#;
-	DOT -> cont 64#;
-	SEMI -> cont 65#;
-	Variable happy_dollar_dollar -> cont 66#;
-	XMLtext happy_dollar_dollar -> cont 67#;
-	TInteger happy_dollar_dollar -> cont 68#;
-	TFloat happy_dollar_dollar -> cont 69#;
-	TString happy_dollar_dollar -> cont 70#;
-	_ -> happyError' (tk:tks)
-	}
-
-happyError_ tk tks = happyError' (tk:tks)
-
-newtype HappyIdentity a = HappyIdentity a
-happyIdentity = HappyIdentity
-happyRunIdentity (HappyIdentity a) = a
-
-instance Monad HappyIdentity where
-    return = HappyIdentity
-    (HappyIdentity p) >>= q = q p
-
-happyThen :: () => HappyIdentity a -> (a -> HappyIdentity b) -> HappyIdentity b
-happyThen = (>>=)
-happyReturn :: () => a -> HappyIdentity a
-happyReturn = (return)
-happyThen1 m k tks = (>>=) m (\a -> k a tks)
-happyReturn1 :: () => a -> b -> HappyIdentity a
-happyReturn1 = \a tks -> (return) a
-happyError' :: () => [Token] -> HappyIdentity a
-happyError' = HappyIdentity . parseError
-
-parse tks = happyRunIdentity happySomeParser where
-  happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))
-
-happySeq = happyDontSeq
-
-
--- Abstract Syntax Tree for XQueries
-data Ast = Ast String [Ast]
-         | Avar String
-         | Aint Int
-         | Afloat Float
-         | Astring String
-         deriving Eq
-
-
-instance Show Ast
-  where show (Ast s []) = s ++ "()"
-        show (Ast s (x:xs)) = s ++ "(" ++ show x
-                              ++ foldr (\a r -> ","++show a++r) "" xs
-                              ++ ")"
-        show (Avar s) = s
-        show (Aint n) = show n
-        show (Afloat n) = show n
-        show (Astring s) = "\'" ++ s ++ "\'"
-
-
-screenSize = 80::Int
-
-prettyAst :: Ast -> Int -> (String,Int)
-prettyAst (Avar s) p = (s,(length s)+p)
-prettyAst (Aint n) p = let s = show n in (s,(length s)+p)
-prettyAst (Afloat n) p = let s = show n in (s,(length s)+p)
-prettyAst (Astring s) p = ("\'" ++ s ++ "\'",(length s)+p+2)
-prettyAst (Ast s args) p
-    = let (ps,np) = prettyArgs args
-      in (s++"("++ps++")",np+1)
-    where prettyArgs [] = ("",p+1)
-          prettyArgs xs = let ss = show (head xs) ++ foldr (\a r -> ","++show a++r) "" (tail xs)
-                              np = (length s)+p+1
-                          in if (length ss)+p < screenSize
-                             then (ss,(length ss)+p)
-                             else let ds = map (\x -> let (s,ep) = prettyAst x np
-                                                      in (s ++ ",\n" ++ space np,ep)) (init xs)
-                                      (ls,lp) = prettyAst (last xs) np
-                                  in (concatMap fst ds ++ ls,lp)
-          space n = replicate n ' '
-
-
-ppAst :: Ast -> String
-ppAst e = let (s,_) = prettyAst e 0 in s
-
-
-call :: String -> [Ast] -> Ast
-call name args = Ast "call" ((Avar name):args)
-
-
-concatenateAll :: [Ast] -> Ast
-concatenateAll [x] = x
-concatenateAll (x:xs) = foldl (\a r -> call "concatenate" [a,r]) x xs
-concatenateAll _ = call "empty" []
-
-
-data Token
-  = RETURN | SOME | EVERY | IF | THEN | ELSE | LB | RB | LP | RP | LSB | RSB
-  | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD
-  | TEQ | TNE | TLT | TLE | TGT | TGE | SEQ | SNE | SLT | SLE | SGT | SGE
-  | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA
-  | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT
-  | ATTRIBUTE | STAG | ETAG | SATISFIES | ATSIGN | SLASH | DECLARE | SEMI
-  | FUNCTION | VARIABLE |AT | DOT | DOTS | TokenEOF | PRE | POST | IS
-  | QName String | Variable String | XMLtext String | TInteger Int
-  | TFloat Float | TString String | TError String
-    deriving Eq
-
-
-instance Show Token
-    where show (QName s) = "QName("++s++")"
-	  show (Variable s) = "Variable("++s++")"
-	  show (XMLtext s) = "XMLtext("++s++")"
-	  show (TInteger n) = "Integer("++(show n)++")"
-	  show (TFloat n) = "Double("++(show n)++")"
-	  show (TString s) = "String("++s++")"
-	  show (TError s) = "'"++s++"'"
-          show t = case filter (\(n,_) -> n==t) tokenList of
-                     (_,b):_ -> b
-                     _ -> "Illegal token"
-
-
-tokenList :: [(Token,String)]
-tokenList = [(RETURN,"return"),(SOME,"some"),(EVERY,"every"),(IF,"if"),(THEN,"then"),(ELSE,"else"),
-             (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"),
-             (TO,"to"),(PLUS,"+"),(MINUS,"-"),(TIMES,"*"),(DIV,"div"),(IDIV,"idiv"),(MOD,"mod"),
-             (TEQ,"="),(TNE,"!="),(TLT,"<"),(TLE,"<="),(TGT,">"),(TGE,">="),(PRE,"<<"),(POST,">>"),
-             (IS,"is"),(SEQ,"eq"),(SNE,"ne"),(SLT,"lt"),(SLE,"le"),(SGT,"gt"),(SGE,"ge"),(AND,"and"),
-             (OR,"or"),(NOT,"not"),(UNION,"union"),(INTERSECT,"intersect"),(EXCEPT,"except"),
-             (FOR,"for"),(LET,"let"),(IN,"in"),(COMMA,"','"),(ASSIGN,":="),(WHERE,"where"),(ORDER,"order"),
-             (BY,"by"),(ASCENDING,"ascending"),(DESCENDING,"descending"),(ELEMENT,"element"),
-             (ATTRIBUTE,"attribute"),(STAG,"</"),(ETAG,"/>"),(SATISFIES,"satisfies"),(ATSIGN,"@"),
-             (SLASH,"/"),(DECLARE,"declare"),(FUNCTION,"function"),(VARIABLE,"variable"),
-             (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";")]
-
-
-parseError tk = error (case tk of
-                         ((TError s):_) -> "Parse error: "++s
-                         _ -> "Parse error: "++(foldr (\a r -> (show a)++" "++r) "" (take 20 tk)))
-
-
-scan :: String -> [Token]
-scan cs = lexer cs ""
-
-
-xmlText :: String -> [Token]
-xmlText "" = []
-xmlText text = [XMLtext text]
-
-
--- scans XML syntax and returns an XMLtext token with the text
-xml :: String -> String -> String -> [Token]
-xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs ('{':n))
-xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs ('<':'/':n))
-xml ('<':'!':'-':cs) text n = xmlComment cs (text++"<!-") n
-xml ('<':cs) text n = (xmlText text)++(TLT : lexer cs ('<':n))
-xml ('(':':':cs) text n = xqComment cs text n
-xml (c:cs) text n = xml cs (text++[c]) n
-xml [] text _ = xmlText text
-
-
-xqComment :: String -> String -> String -> [Token]
-xqComment (':':')':cs) text n = xml cs text n
-xqComment (_:cs) text n = xqComment cs text n
-xqComment [] text _ = xmlText text
-
-
-xmlComment :: String -> String -> String -> [Token]
-xmlComment ('-':'>':cs) text n = xml cs (text++"->") n
-xmlComment (c:cs) text n = xmlComment cs (text++[c]) n
-xmlComment [] text _ = xmlText text
-
-
-isQN :: Char -> Bool
-isQN c = elem c "_:-" || isDigit c || isAlpha c
-
-
-isVar :: Char -> Bool
-isVar c = elem c "_" || isDigit c || isAlpha c
-
-
-inXML :: String -> Bool
-inXML ('>':'<':_) = True
-inXML _ = False
-
-
--- the XQuery scanner
-lexer :: String -> String -> [Token]
-lexer [] "" = []
-lexer [] _ = [ TError "Unexpected end of input" ]
-lexer (' ':'>':' ':cs) n = TGT : lexer cs n
-lexer (c:cs) n
-      | isSpace c = lexer cs n
-      | isAlpha c = lexVar (c:cs) n
-      | isDigit c = lexNum (c:cs) n
-lexer ('$':c:cs) n | isAlpha c
-      = let (var,rest) = span isVar (c:cs)
-        in (Variable var) : lexer rest n
-lexer (':':'=':cs) n = ASSIGN : lexer cs n
-lexer ('<':'/':cs) n = STAG : lexer cs ('<':'/':n)
-lexer ('<':'=':cs) n = TLE : lexer cs n
-lexer ('>':'=':cs) n = TGE : lexer cs n
-lexer ('<':'<':cs) n = PRE : lexer cs n
-lexer ('>':'>':cs) n = POST : lexer cs n
-lexer ('/':'>':cs) m = case m of
-                         '<':n -> ETAG : (if inXML n then xml cs "" n else lexer cs n)
-                         _ -> [ TError "Unexpected token: '/>'" ]
-lexer ('(':':':cs) n = lexComment cs n
-lexer ('<':'!':'-':cs) n = lexXmlComment cs "<!-" n
-lexer ('.':'.':cs) n = DOTS : lexer cs n
-lexer ('.':cs) n = DOT : lexer cs n
-lexer ('!':'=':cs) n = TNE : lexer cs n
-lexer ('\'':cs) n = lexString cs "" ('\'':n)
-lexer ('\"':cs) n = lexString cs "" ('\"': n)
-lexer ('[':cs) n = LB : lexer cs n
-lexer (']':cs) n = RB : lexer cs n
-lexer ('(':cs) n = LP : lexer cs n
-lexer (')':cs) n = RP : lexer cs n
-lexer ('}':cs) m = case m of
-                     '{':'\"':n -> RSB : lexString cs "" ('\"':n)
-                     '{':'\'':n -> RSB : lexString cs "" ('\'':n)
-                     '{':n -> RSB : (if inXML n then xml cs "" n else lexer cs n)
-                     _ -> [ TError "Unexpected token: '}'" ]
-lexer ('+':cs) n = PLUS : lexer cs n
-lexer ('-':cs) n = MINUS : lexer cs n
-lexer ('*':cs) n = TIMES : lexer cs n
-lexer ('=':cs) n = TEQ : lexer cs n
-lexer ('<':c:cs) n = TLT : (lexer (c:cs) (if isAlpha c then ('<':n) else n))
-lexer ('>':cs) m = case m of
-                     '<':'/':'>':'<':n -> TGT : (if inXML n then xml cs "" n else lexer cs n)
-                     '<':n -> TGT : xml cs "" ('>':m) 
-                     _ -> TGT : lexer cs m
-lexer (',':cs) n = COMMA : lexer cs n
-lexer ('@':cs) n = ATSIGN : lexer cs n
-lexer ('/':cs) n = SLASH : lexer cs n
-lexer ('{':cs) n = LSB : lexer cs ('{':n)
-lexer ('|':cs) n = UNION : lexer cs n
-lexer (';':cs) n = SEMI : lexer cs n
-lexer (c:cs) n = TError ("Illegal character: '"++[c,'\'']) : lexer cs n
-
-
-lexNum :: String -> String -> [Token]
-lexNum cs n = if null rest || head rest /= '.'
-                 then TInteger (read k) : lexer rest n
-              else let (m,rest2) = span isDigit (tail rest)
-                       val::Float = read (k++('.':m))
-                   in case rest2 of
-                        ('e':rest3) -> let (exp,rest4) = span isDigit rest3
-                                       in (TFloat (val*10^(read exp))) : lexer rest4 n
-                        _ -> (TFloat val) : lexer rest2 n
-      where (k,rest) = span isDigit cs
-
-
-lexString :: String -> String -> String -> [Token]
-lexString ('\"':cs) s m = case m of
-                            '\"':n -> (TString s) : (lexer cs n)
-                            _ -> lexString cs (s++"\"") m
-lexString ('\'':cs) s m = case m of
-                            '\'':n -> (TString s) : (lexer cs n)
-                            _ -> lexString cs (s++"\'") m
-lexString ('{':cs) s n = (TString s) : LSB : (lexer cs ('{':n))
-lexString (c:cs) s n = lexString cs (s++[c]) n
-lexString [] s n = [ TError "End of input while in string" ]
-
-
-lexComment :: String -> String -> [Token]
-lexComment (':':')':cs) n = lexer cs n
-lexComment (_:cs) n = lexComment cs n
-lexComment [] n = [ TError "End of input while in comment" ]
-
-
-lexXmlComment :: String -> String -> String -> [Token]
-lexXmlComment ('-':'>':cs) text n = (xmlText (text++"->"))++(lexer cs n)
-lexXmlComment (c:cs) text n = lexXmlComment cs (text++[c]) n
-lexXmlComment [] text _ = xmlText text
-
-
-lexVar :: String -> String -> [Token]
-lexVar cs n =
-    let (nm,rest) = span isQN cs
-    in (case nm of
-          "return" -> RETURN
-          "some" -> SOME
-          "every" -> EVERY
-          "if" -> IF
-          "then" -> THEN
-          "else" -> ELSE
-          "to" -> TO
-          "div" -> DIV
-          "idiv" -> IDIV
-          "mod" -> MOD
-          "and" -> AND
-          "or" -> OR
-          "not" -> NOT
-          "union" -> UNION
-          "intersect" -> INTERSECT
-          "except" -> EXCEPT
-          "for" -> FOR
-          "let" -> LET
-          "in" -> IN
-          "where" -> WHERE
-          "order" -> ORDER
-          "by" -> BY
-          "ascending" -> ASCENDING
-          "descending" -> DESCENDING
-          "element" -> ELEMENT
-          "attribute" -> ATTRIBUTE
-          "satisfies" -> SATISFIES
-          "declare" -> DECLARE
-          "function" -> FUNCTION
-          "variable" -> VARIABLE
-          "at" -> AT
-          "eq" -> SEQ
-          "ne" -> SNE
-          "lt" -> SLT
-          "le" -> SLE
-          "gt" -> SGT
-          "ge" -> SGE
-          "is" -> IS
-          var -> QName var
-       ) : lexer rest n
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
-{-# LINE 1 "<built-in>" #-}
-{-# LINE 1 "<command line>" #-}
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
--- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp 
-
-{-# LINE 28 "templates/GenericTemplate.hs" #-}
-
-
-data Happy_IntList = HappyCons Int# Happy_IntList
-
-
-
-
-
-{-# LINE 49 "templates/GenericTemplate.hs" #-}
-
-{-# LINE 59 "templates/GenericTemplate.hs" #-}
-
-{-# LINE 68 "templates/GenericTemplate.hs" #-}
-
-infixr 9 `HappyStk`
-data HappyStk a = HappyStk a (HappyStk a)
-
------------------------------------------------------------------------------
--- starting the parse
-
-happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll
-
------------------------------------------------------------------------------
--- Accepting the parse
-
--- If the current token is 0#, it means we've just accepted a partial
--- parse (a %partial parser).  We must ignore the saved token on the top of
--- the stack in this case.
-happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =
-	happyReturn1 ans
-happyAccept j tk st sts (HappyStk ans _) = 
-	(happyTcHack j (happyTcHack st)) (happyReturn1 ans)
-
------------------------------------------------------------------------------
--- Arrays only: do the next action
-
-
-
-happyDoAction i tk st
-	= {- nothing -}
-
-
-	  case action of
-		0#		  -> {- nothing -}
-				     happyFail i tk st
-		-1# 	  -> {- nothing -}
-				     happyAccept i tk st
-		n | (n <# (0# :: Int#)) -> {- nothing -}
-
-				     (happyReduceArr ! rule) i tk st
-				     where rule = (I# ((negateInt# ((n +# (1# :: Int#))))))
-		n		  -> {- nothing -}
-
-
-				     happyShift new_state i tk st
-				     where new_state = (n -# (1# :: Int#))
-   where off    = indexShortOffAddr happyActOffsets st
-	 off_i  = (off +# i)
-	 check  = if (off_i >=# (0# :: Int#))
-			then (indexShortOffAddr happyCheck off_i ==#  i)
-			else False
- 	 action | check     = indexShortOffAddr happyTable off_i
-		| otherwise = indexShortOffAddr happyDefActions st
-
-{-# LINE 127 "templates/GenericTemplate.hs" #-}
-
-
-indexShortOffAddr (HappyA# arr) off =
-#if __GLASGOW_HASKELL__ > 500
-	narrow16Int# i
-#elif __GLASGOW_HASKELL__ == 500
-	intToInt16# i
-#else
-	(i `iShiftL#` 16#) `iShiftRA#` 16#
-#endif
-  where
-#if __GLASGOW_HASKELL__ >= 503
-	i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)
-#else
-	i = word2Int# ((high `shiftL#` 8#) `or#` low)
-#endif
-	high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
-	low  = int2Word# (ord# (indexCharOffAddr# arr off'))
-	off' = off *# 2#
-
-
-
-
-
-data HappyAddr = HappyA# Addr#
-
-
-
-
------------------------------------------------------------------------------
--- HappyState data type (not arrays)
-
-{-# LINE 170 "templates/GenericTemplate.hs" #-}
-
------------------------------------------------------------------------------
--- Shifting a token
-
-happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =
-     let i = (case unsafeCoerce# x of { (I# (i)) -> i }) in
---     trace "shifting the error token" $
-     happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)
-
-happyShift new_state i tk st sts stk =
-     happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)
-
--- happyReduce is specialised for the common cases.
-
-happySpecReduce_0 i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happySpecReduce_0 nt fn j tk st@((action)) sts stk
-     = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)
-
-happySpecReduce_1 i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')
-     = let r = fn v1 in
-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
-
-happySpecReduce_2 i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')
-     = let r = fn v1 v2 in
-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
-
-happySpecReduce_3 i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')
-     = let r = fn v1 v2 v3 in
-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
-
-happyReduce k i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happyReduce k nt fn j tk st sts stk
-     = case happyDrop (k -# (1# :: Int#)) sts of
-	 sts1@((HappyCons (st1@(action)) (_))) ->
-        	let r = fn stk in  -- it doesn't hurt to always seq here...
-       		happyDoSeq r (happyGoto nt j tk st1 sts1 r)
-
-happyMonadReduce k nt fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happyMonadReduce k nt fn j tk st sts stk =
-        happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))
-       where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts))
-             drop_stk = happyDropStk k stk
-
-happyMonad2Reduce k nt fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happyMonad2Reduce k nt fn j tk st sts stk =
-       happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))
-       where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts))
-             drop_stk = happyDropStk k stk
-
-             off    = indexShortOffAddr happyGotoOffsets st1
-             off_i  = (off +# nt)
-             new_state = indexShortOffAddr happyTable off_i
-
-
-
-
-happyDrop 0# l = l
-happyDrop n (HappyCons (_) (t)) = happyDrop (n -# (1# :: Int#)) t
-
-happyDropStk 0# l = l
-happyDropStk n (x `HappyStk` xs) = happyDropStk (n -# (1#::Int#)) xs
-
------------------------------------------------------------------------------
--- Moving to a new state after a reduction
-
-
-happyGoto nt j tk st = 
-   {- nothing -}
-   happyDoAction j tk new_state
-   where off    = indexShortOffAddr happyGotoOffsets st
-	 off_i  = (off +# nt)
- 	 new_state = indexShortOffAddr happyTable off_i
-
-
-
-
------------------------------------------------------------------------------
--- Error recovery (0# is the error token)
-
--- parse error if we are in recovery and we fail again
-happyFail  0# tk old_st _ stk =
---	trace "failing" $ 
-    	happyError_ tk
-
-{-  We don't need state discarding for our restricted implementation of
-    "error".  In fact, it can cause some bogus parses, so I've disabled it
-    for now --SDM
-
--- discard a state
-happyFail  0# tk old_st (HappyCons ((action)) (sts)) 
-						(saved_tok `HappyStk` _ `HappyStk` stk) =
---	trace ("discarding state, depth " ++ show (length stk))  $
-	happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))
--}
-
--- Enter error recovery: generate an error token,
---                       save the old token and carry on.
-happyFail  i tk (action) sts stk =
---      trace "entering error recovery" $
-	happyDoAction 0# tk action sts ( (unsafeCoerce# (I# (i))) `HappyStk` stk)
-
--- Internal happy errors:
-
-notHappyAtAll = error "Internal Happy error\n"
-
------------------------------------------------------------------------------
--- Hack to get the typechecker to accept our action functions
-
-
-happyTcHack :: Int# -> a -> a
-happyTcHack x y = y
-{-# INLINE happyTcHack #-}
-
-
------------------------------------------------------------------------------
--- Seq-ing.  If the --strict flag is given, then Happy emits 
---	happySeq = happyDoSeq
--- otherwise it emits
--- 	happySeq = happyDontSeq
-
-happyDoSeq, happyDontSeq :: a -> b -> b
-happyDoSeq   a b = a `seq` b
-happyDontSeq a b = b
-
------------------------------------------------------------------------------
--- Don't inline any functions from the template.  GHC has a nasty habit
--- of deciding to inline happyGoto everywhere, which increases the size of
--- the generated parser quite a bit.
-
-
-{-# NOINLINE happyDoAction #-}
-{-# NOINLINE happyTable #-}
-{-# NOINLINE happyCheck #-}
-{-# NOINLINE happyActOffsets #-}
-{-# NOINLINE happyGotoOffsets #-}
-{-# NOINLINE happyDefActions #-}
-
-{-# NOINLINE happyShift #-}
-{-# NOINLINE happySpecReduce_0 #-}
-{-# NOINLINE happySpecReduce_1 #-}
-{-# NOINLINE happySpecReduce_2 #-}
-{-# NOINLINE happySpecReduce_3 #-}
-{-# NOINLINE happyReduce #-}
-{-# NOINLINE happyMonadReduce #-}
-{-# NOINLINE happyGoto #-}
-{-# NOINLINE happyFail #-}
-
--- end of Happy Template.
diff --git a/XML/HXQ/XQuery.hs b/XML/HXQ/XQuery.hs
deleted file mode 100644
--- a/XML/HXQ/XQuery.hs
+++ /dev/null
@@ -1,43 +0,0 @@
-{-------------------------------------------------------------------------------------
--
-- The XQuery Compiler and Interpreter
-- Programmer: Leonidas Fegaras
-- Email: fegaras@cse.uta.edu
-- Web: http://lambda.uta.edu/
-- Creation: 03/22/08, last update: 05/30/08
-- 
-- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
-- This material is provided as is, with absolutely no warranty expressed or implied.
-- Any use is at your own risk. Permission is hereby granted to use or copy this program
-- for any purpose, provided the above notices are retained on all copies.
--
---------------------------------------------------------------------------------------}
-
-
--- | HXQ is a fast and space-efficient compiler from XQuery (the standard
--- query language for XML) to embedded Haskell code. The translation is
--- based on Haskell templates. It also provides an interpreter for
--- evaluating ad-hoc XQueries read from input or from files and database connectivity using HDBC.
--- For more information, look at <http://lambda.uta.edu/HXQ/>.
-module XML.HXQ.XQuery (
-       -- * The XML Data Representation
-       XTree(..), XSeq, Tag, AttList, putXSeq,
-       -- * The XQuery Compiler
-       xq, xe,
-       -- * The XQuery Interpreter
-       xquery, xfile,
-       -- * The XQuery Compiler with Database Connectivity
-       xqdb, connect, disconnect, prepareSQL, executeSQL,
-       -- * The XQuery Interpreter with Database Connectivity
-       xqueryDB, xfileDB,
-       -- * Shredding and Publishing XML Documents Using a Relational Database
-       shred, createIndex
-    ) where
-
-import HXML(AttList)
-import XML.HXQ.XTree
-import XML.HXQ.Compiler
-import XML.HXQ.Interpreter
-import XML.HXQ.DB
-import XML.HXQ.DBConnect
-import Database.HDBC(disconnect)
diff --git a/XML/HXQ/XTree.hs b/XML/HXQ/XTree.hs
deleted file mode 100644
--- a/XML/HXQ/XTree.hs
+++ /dev/null
@@ -1,147 +0,0 @@
-{-------------------------------------------------------------------------------------
--
-- XML Trees (represented as rose trees)
-- Programmer: Leonidas Fegaras
-- Email: fegaras@cse.uta.edu
-- Web: http://lambda.uta.edu/
-- Creation: 05/01/08, last update: 05/30/08
-- 
-- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
-- This material is provided as is, with absolutely no warranty expressed or implied.
-- Any use is at your own risk. Permission is hereby granted to use or copy this program
-- for any purpose, provided the above notices are retained on all copies.
--
---------------------------------------------------------------------------------------}
-
-
-{-# OPTIONS_GHC -funbox-strict-fields #-}
-
-
-module XML.HXQ.XTree where
-
-import System.IO
-import XMLParse(XMLEvent(..))
-import HXML(AttList)
-import XML.HXQ.Parser(Ast(..))
-import Database.HDBC(Statement)
-
-
-instance Eq Statement where x == y = False
-
-
-type Tag = String
-
-
--- | Rose tree representation of XML data.
--- The Int in XElem is the preorder numbering used for the document order of nodes.
-data XTree =  XElem    !Tag !AttList !Int XTree [XTree]   -- ^ an XML tree node (element)
-           |  XText    !String          -- ^ an XML tree leaf (PCDATA)
-           |  XInt     !Int             -- ^ an XML tree leaf (int)
-           |  XFloat   !Float           -- ^ an XML tree leaf (float)
-           |  XBool    !Bool            -- ^ an XML tree leaf (boolean)
-           |  XPI      Tag String	-- ^ processing instruction
-           |  XGERef   Tag		-- ^ general entity reference
-           |  XComment String		-- ^ comment
-           |  XError   String		-- ^ error report
-           |  XStmt    Statement        -- ^ used internally to wrap an SQL statement
-           |  XNoPad                    -- ^ marker for no padding in XSeq
-           deriving Eq
-
-
-type XSeq = [XTree]
-
-
-showAL :: AttList -> String
-showAL = foldr (\(a,v) r -> " "++a++"=\""++v++"\""++r) []
-
-showXT :: XTree -> Bool -> String
-showXT e pad
-    = case e of
-        XElem tag al _ _ [] -> "<"++tag++showAL al++"/>"
-        XElem tag al _ _ xs -> "<"++tag++showAL al++">"++showXS xs++"</"++tag++">"
-        XText text -> p++text
-        XInt n -> p++show n
-        XFloat n -> p++show n
-        XBool v -> p++if v then "true" else "false"
-        XComment s -> "<!--"++s++"-->"
-        XPI n s -> "<?"++n++" "++s++">"
-        XError s -> error s
-        _ -> ""
-      where p = if pad then " " else ""
-
-showXS :: XSeq -> String
-showXS [] = ""
-showXS (x:xs) = showXT x False ++ sXS xs
-    where sXS (XNoPad:x:xs) = (showXT x False) ++ sXS xs
-          sXS (x:xs) = (showXT x True) ++ sXS xs
-          sXS _ = ""
-
-instance Show XTree where
-    show t = showXT t False
-
-
--- | Print the XQuery result (which is a sequence of XML fragments) without buffering.
-putXSeq :: XSeq -> IO ()
-putXSeq xs = hSetBuffering stdout NoBuffering >> putStrLn (showXS xs)
-
-
-
-{--------------- Build the rose tree from the XML stream ----------------------------}
-
-
-type Stream = [XMLEvent]
-
-noParentError = error "parent references are not supported yet"
-
--- lazily materialize the SAX stream into a DOM tree
-materializeWithoutParent :: Stream -> XTree
-materializeWithoutParent stream
-    = XElem "document" [] 1 noParentError
-            [head (filter (\x -> case x of XElem _ _ _ _ _ -> True; _ -> False)
-                          ((\(x,_,_)->x) (ml stream 2)))]
-      where m ((TextEvent t):xs) i = (XText t,xs,i)
-            m ((EmptyEvent n atts):xs) i = (XElem n atts i noParentError [],xs,i+1)
-            m ((StartEvent n atts):xs) i
-                = let (el,xs',i') = ml xs (i+1)
-                  in (XElem n atts i noParentError el,xs',i')
-            m ((PIEvent n s):xs) i = (XPI n s,xs,i)
-            m ((CommentEvent s):xs) i = (XComment s,xs,i)
-            m ((GERefEvent n):xs) i = (XGERef n,xs,i)
-            m ((ErrorEvent s):xs) i = (XError s,xs,i)
-            m (_:xs) i = (XError "unrecognized XML event",xs,i)
-            m [] i = (XError "unbalanced tags",[],i)
-            ml [] i = ([],[],i)
-            ml ((EndEvent n):xs) i = ([],xs,i)
-            ml xs i = let (e,xs',i') = m xs i
-                          (el,xs'',i'') = ml xs' i'
-                      in (e:el,xs'',i'')
-
-
--- lazily materialize the SAX stream into a DOM tree that contains parent references
--- Not used because it has space leaks for large documents
-materializeWithParent :: Stream -> XTree
-materializeWithParent stream = root
-    where root = XElem "document" [] 1 (error "Trying to access the root parent")
-                       [head (filter (\x -> case x of XElem _ _ _ _ _ -> True; _ -> False)
-                                     ((\(x,_,_)->x) (ml stream 2 root)))]
-          m ((TextEvent t):xs) i _ = (XText t,xs,i)
-          m ((EmptyEvent n atts):xs) i p = (XElem n atts i p [],xs,i+1)
-          m ((StartEvent n atts):xs) i p
-              = let (el,xs',i') = ml xs (i+1) node
-                    node = XElem n atts i p el
-                in (node,xs',i')
-          m ((PIEvent n s):xs) i _ = (XPI n s,xs,i)
-          m ((CommentEvent s):xs) i _ = (XComment s,xs,i)
-          m ((GERefEvent n):xs) i _ = (XGERef n,xs,i)
-          m ((ErrorEvent s):xs) i _ = (XError s,xs,i)
-          m (_:xs) i _ = (XError "unrecognized XML event",xs,i)
-          m [] i _ = (XError "unbalanced tags",[],i)
-          ml [] i _ = ([],[],i)
-          ml ((EndEvent n):xs) i _ = ([],xs,i)
-          ml xs i p = let (e,xs',i') = m xs i p
-                          (el,xs'',i'') = ml xs' i' p
-                      in (e:el,xs'',i'')
-
-
-materialize :: Stream -> XTree
-materialize = materializeWithoutParent
diff --git a/XQueryParser.y b/XQueryParser.y
--- a/XQueryParser.y
+++ b/XQueryParser.y
@@ -4,7 +4,7 @@
 - Programmer: Leonidas Fegaras
 - Email: fegaras@cse.uta.edu
 - Web: http://lambda.uta.edu/
-- Creation: 02/15/08, last update: 05/15/08
+- Creation: 02/15/08, last update: 07/24/08
 - 
 - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
 - This material is provided as is, with absolutely no warranty expressed or implied.
@@ -14,7 +14,7 @@
 --------------------------------------------------------------------------------------}
 
 {
-module XML.HXQ.Parser where
+module Text.XML.HXQ.Parser where
 import Char
 }
 
diff --git a/index.html b/index.html
--- a/index.html
+++ b/index.html
@@ -45,7 +45,7 @@
 <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-sqlite3">HDBC-sqlite3</a> driver
 to connect to SQLite relational databases.
 <p>
-Finally, download <a href="/HXQ-0.8.4.tar.gz">HXQ</a> and untar it.
+Finally, download <a href="/HXQ-0.8.5.tar.gz">HXQ</a> and untar it.
 You can use either make or cabal to build it. To build it with cabal, you do:
 <pre>
 runhaskell Setup.lhs configure --prefix=$HOME
@@ -158,7 +158,7 @@
 Currently, HXQ works with <a href="http://sqlite.org/">SQLite</a> only, but is very easy to make it work
 with any relational database that supports ODBC: simply install 
 <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-odbc">HDBC-odbc</a>
-and change the file <a href="XML/HXQ/DBConnect.hs">XML/HXQ/DBConnect.hs</a> accordingly.
+and change the file <a href="Text/XML/HXQ/DBConnect.hs">Text/XML/HXQ/DBConnect.hs</a> accordingly.
 <p>
 <h3>Querying an Existing Database</h3>
 <p>
@@ -220,4 +220,4 @@
 <p>
 <hr>
 <p>
-<address>Last modified: 06/27/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
+<address>Last modified: 07/24/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
