diff --git a/Dvda/Expr.hs b/Dvda/Expr.hs
--- a/Dvda/Expr.hs
+++ b/Dvda/Expr.hs
@@ -23,11 +23,13 @@
                  , getConst
                  , substitute
                  , sketchySubstitute
+                 , foldExpr
                  ) where
 
 import Control.Applicative ( (<$>), (<*>), pure )
 import Data.Data ( Data, Typeable, Typeable1, Typeable2 )
 import Data.Hashable ( Hashable, hash, combine )
+import Data.Ratio ( (%) )
 
 --import Test.QuickCheck -- ( Arbitrary(..) )
 
@@ -243,6 +245,9 @@
   (*) (EFractional (FromRational rx)) (EConst y) = EConst $ fromRational rx * y
   (*) (ENum (FromInteger kx)) (EFractional (FromRational ry)) = EFractional $ FromRational (fromInteger kx * ry)
   (*) (EFractional (FromRational rx)) (ENum (FromInteger ky)) = EFractional $ FromRational (rx * fromInteger ky)
+  (*) (ENum (Negate x)) (ENum (Negate y)) = x * y
+  (*) (ENum (Negate x)) y = negate (x * y)
+  (*) x (ENum (Negate y)) = negate (x * y)
   (*) x y
     | isVal 0 x || isVal 0 y = 0
     | isVal 1 x = y
@@ -258,9 +263,13 @@
   (+) (EFractional (FromRational rx)) (EConst y) = EConst $ fromRational rx + y
   (+) (ENum (FromInteger kx)) (EFractional (FromRational ry)) = EFractional $ FromRational (fromInteger kx + ry)
   (+) (EFractional (FromRational rx)) (ENum (FromInteger ky)) = EFractional $ FromRational (rx + fromInteger ky)
+  (+) (ENum (Negate x)) (ENum (Negate y)) = negate (x + y)
+  (+) x (ENum (Negate y)) = x - y
+  (+) (ENum (Negate x)) y = y - x
   (+) x y
     | isVal 0 x = y
     | isVal 0 y = x
+    | x == negate y = 0
     | otherwise = ENum $ Add x y
 
   (-) (EConst x) (EConst y) = EConst (x-y)
@@ -272,9 +281,13 @@
   (-) (EFractional (FromRational rx)) (EConst y) = EConst $ fromRational rx - y
   (-) (ENum (FromInteger kx)) (EFractional (FromRational ry)) = EFractional $ FromRational (fromInteger kx - ry)
   (-) (EFractional (FromRational rx)) (ENum (FromInteger ky)) = EFractional $ FromRational (rx - fromInteger ky)
+  (-) (ENum (Negate x)) (ENum (Negate y)) = y - x -- (-x) - (-y) == y - x
+  (-) x (ENum (Negate y)) = x + y -- (x) - (-y) == x + y
+  (-) (ENum (Negate x)) y = negate (x + y) -- (-x) - (y) == -(x+y)
   (-) x y
     | isVal 0 x = negate y
     | isVal 0 y = x
+    | x == y = 0
     | otherwise = ENum $ Sub x y
 
   abs (EConst x) = EConst (abs x)
@@ -285,6 +298,7 @@
   negate (EConst x) = EConst (negate x)
   negate (ENum (FromInteger k)) = ENum (FromInteger (negate k))
   negate (EFractional (FromRational r)) = EFractional (FromRational (negate r))
+  negate (ENum (Negate x)) = x
   negate x = ENum $ Negate x
 
   signum (EConst x) = EConst (signum x)
@@ -296,7 +310,7 @@
 
 instance (Fractional a, Eq a) => Fractional (Expr a) where
   (/) (EConst x) (EConst y) = EConst (x/y)
---  (/) (ENum (FromInteger kx)) (ENum (FromInteger ky)) = ENum $ FromInteger (kx / ky)
+  (/) (ENum (FromInteger kx)) (ENum (FromInteger ky)) = EFractional $ FromRational (kx % ky)
   (/) (EFractional (FromRational rx)) (EFractional (FromRational ry)) = EFractional $ FromRational (rx / ry)
   (/) (EConst x) (ENum (FromInteger ky)) = EConst $ x / fromInteger ky
   (/) (ENum (FromInteger kx)) (EConst y) = EConst $ fromInteger kx / y
@@ -304,6 +318,9 @@
   (/) (EFractional (FromRational rx)) (EConst y) = EConst $ fromRational rx / y
   (/) (ENum (FromInteger kx)) (EFractional (FromRational ry)) = EFractional $ FromRational (fromInteger kx / ry)
   (/) (EFractional (FromRational rx)) (ENum (FromInteger ky)) = EFractional $ FromRational (rx / fromInteger ky)
+  (/) (ENum (Negate x)) (ENum (Negate y)) = x / y
+  (/) (ENum (Negate x)) y = negate (x / y)
+  (/) x (ENum (Negate y)) = negate (x / y)
   (/) x y
     | isVal 0 y = error "Fractional (Expr a) divide by zero"
     | isVal 0 x = 0
@@ -528,6 +545,35 @@
 
 
 ---------------------------------- utility functions -------------------------------
+-- | foldr over the constants and symbols
+foldExpr :: (Expr a -> b -> b) -> b -> Expr a -> b
+foldExpr f acc e@(ESym _)                       = f e acc
+foldExpr f acc e@(EConst _)                     = f e acc
+foldExpr f acc e@(EFractional (FromRational _)) = f e acc
+foldExpr f acc e@(ENum (FromInteger _))         = f e acc
+foldExpr f acc (ENum (Mul x y))          = foldExpr f (foldExpr f acc y) x
+foldExpr f acc (ENum (Add x y))          = foldExpr f (foldExpr f acc y) x
+foldExpr f acc (ENum (Sub x y))          = foldExpr f (foldExpr f acc y) x
+foldExpr f acc (ENum (Negate x))         = foldExpr f acc x
+foldExpr f acc (ENum (Abs x))            = foldExpr f acc x
+foldExpr f acc (ENum (Signum x))         = foldExpr f acc x
+foldExpr f acc (EFractional (Div x y))   = foldExpr f (foldExpr f acc y) x
+foldExpr f acc (EFloating (Pow x y))     = foldExpr f (foldExpr f acc y) x
+foldExpr f acc (EFloating (LogBase x y)) = foldExpr f (foldExpr f acc y) x
+foldExpr f acc (EFloating (Exp x))       = foldExpr f acc x
+foldExpr f acc (EFloating (Log x))       = foldExpr f acc x
+foldExpr f acc (EFloating (Sin x))       = foldExpr f acc x
+foldExpr f acc (EFloating (Cos x))       = foldExpr f acc x
+foldExpr f acc (EFloating (ASin x))      = foldExpr f acc x
+foldExpr f acc (EFloating (ATan x))      = foldExpr f acc x
+foldExpr f acc (EFloating (ACos x))      = foldExpr f acc x
+foldExpr f acc (EFloating (Sinh x))      = foldExpr f acc x
+foldExpr f acc (EFloating (Cosh x))      = foldExpr f acc x
+foldExpr f acc (EFloating (Tanh x))      = foldExpr f acc x
+foldExpr f acc (EFloating (ASinh x))     = foldExpr f acc x
+foldExpr f acc (EFloating (ATanh x))     = foldExpr f acc x
+foldExpr f acc (EFloating (ACosh x))     = foldExpr f acc x
+
 
 -- | symbolic scalar
 sym :: String -> Expr a
diff --git a/dvda.cabal b/dvda.cabal
--- a/dvda.cabal
+++ b/dvda.cabal
@@ -1,5 +1,5 @@
 Name:                dvda
-Version:             0.3
+Version:             0.3.0.1
 License:             BSD3
 License-file:        LICENSE
 Author:              Greg Horn
